题意:目标是拿到值为-1的宝石,但是前提是要有一条从二维格子外面到宝石的通路,如果没有就要每次选一个石头使它的值减1,直到石头的值为0则变为通路,能选这个石头的前提也是有一条格子外到该石头的通路,A和B开始游戏,两人轮流来,每次选一个石头,A先开始,求由输入的条件,谁能赢。
分析:
博弈问题,两人会把围住宝石的一圈石头外面的石头全部敲碎然后才选这一圈石头,所以就是计算这一圈石头外面的所有石头的值的和,再加上这一圈石头的值减一的和,通过奇偶就能判断谁赢。
实现方法:从宝石dfs找出围住它的一圈石头,用vis[][]数组标记这之内包括这一圈石头的范围,然后从这个圈外面bfs扫描一遍。
bfs和dfs的使用还是很广的,继续通过练习深入理解掌握它的应用。
另外cin cout超时了 = =
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,m,a[1000][1000]; int d[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int vis1[1000][1000],vis2[1000][1000]; int ans; struct node{ int x,y; }; queue<node> q; bool dfs(int x,int y) { if(x==0||x==n-1||y==0||y==m-1) return true; for(int i=0;i<4;i++){ int dx=x+d[i][0]; int dy=y+d[i][1]; if(dx>=0&&dx<n&&dy>=0&&dy<m&&!vis1[dx][dy]){ vis1[dx][dy]=1; if(a[dx][dy]<=0) if(dfs(dx,dy)) return true; } } return false; } void bfs() { while(!q.empty()){ node tmp=q.front(); q.pop(); for(int i=0;i<4;i++){ int dx=tmp.x+d[i][0]; int dy=tmp.y+d[i][1]; if(dx>=0&&dx<n&&dy>=0&&dy<m&&!vis2[dx][dy]){ vis2[dx][dy]=1; if(vis1[dx][dy]) ans+=a[dx][dy]-1; else{ ans+=a[dx][dy]; node tmp2; tmp2.x=dx,tmp2.y=dy; q.push(tmp2); } } } } } int main() { while(scanf("%d%d",&n,&m)!=EOF){ int sx,sy; for(int i=0;i<n;i++) for(int j=0;j<m;j++){ scanf("%d",&a[i][j]); if(a[i][j]==-1) sx=i,sy=j; } memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); if(dfs(sx,sy)) printf("Ali Win\n"); else{ ans=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++){ if(!vis2[i][j]){ if(i==0||i==n-1||j==0||j==m-1){ vis2[i][j]=1; if(!vis1[i][j]){ while(!q.empty()) q.pop(); ans+=a[i][j]; node tmp; tmp.x=i,tmp.y=j; q.push(tmp); bfs(); } else ans+=a[i][j]-1; } } } if(ans%2==1) printf("Ali Win\n"); else printf("Baba Win\n"); } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
!HDU 4101 Ali and Baba-博弈-(bfs&dfs扫描二维点)
原文地址:http://blog.csdn.net/ac_0_summer/article/details/47049063