bfs+博弈 坑爹的hdu,用dfs会爆栈 只能用bfs了,用两边bfs 第一遍用来判断Ali能否一步找到财富,就是看外围是否有一条路通向(-1),再就是标记内边界,再就是第二遍从外面bfs来找寻真正的边界;其实这个题最终形态就是化为
5 1 5 0 1 0
6 -1 6 -> 1 -1 1
8 9 8 0 1 0
当化为诸如此类的形态后 下一次攻击石头的人就会输,所以只要判一下外面石头的奇偶性就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #define N 310 using std::vector; using std::cout; using std::endl; int n,m; int vis[N][N]; int map[N][N]; int a[N][N]; bool ok; int sum,ans; struct dat { int nx,ny; void f(int x, int y) { nx=x,ny=y; } } b,c; vector<dat>p; int move[4][2]= {{0,1},{0,-1},{1,0},{-1,0}}; void find(int s, int v) { p.clear(); b.f(s,v); p.push_back(b); int front=1,rear=0; while(rear<front) { c=p[rear++]; if(c.nx==0 || c.nx==n-1 || c.ny==0 || c.ny==m-1) { ok=true; break; } for(int i=0; i<4; i++) { int x=c.nx+move[i][0]; int y=c.ny+move[i][1]; if(!vis[x][y] && !map[x][y] && x>=0 && x<n && y>=0 && y<m) { vis[x][y]=1; b.f(x,y); p.push_back(b); front++; } else if(!vis[x][y] && map[x][y]==2 && x>=0 && x<n && y>=0 && y<m) { map[x][y]=1; vis[x][y]=1; } } } } int bfsfind(int s, int v) { p.clear(); int front=1,rear=0; vis[s][v]=1; if(map[s][v]==2) sum+=a[s][v]; else if(map[s][v]==1) { sum+=a[s][v]-1; return 0; } b.f(s,v); p.push_back(b); vis[s][v]=1; while(front>rear) { c=p[rear++]; for(int i=0; i<4; i++) { int x=c.nx+move[i][0]; int y=c.ny+move[i][1]; if(!vis[x][y] && !map[x][y] && x>=0 && x<n && y>=0 && y<m) { vis[x][y]=1; b.f(x,y); p.push_back(b); front++; } else if(!vis[x][y] && map[x][y]==1 && x>=0 && x<n && y>=0 && y<m) { sum+=a[x][y]-1; vis[x][y]=1; } else if(!vis[x][y] && map[x][y]==2 && x>=0 && x<n && y>=0 && y<m) { sum+=a[x][y]; vis[x][y]=1; b.f(x,y); p.push_back(b); front++; } } } } int main() { while(scanf("%d %d",&n,&m)==2) { memset(map, 0, sizeof(map)); int _x,_y; for(int i=0; i<n; i++) { for(int j=0; j<m; ++j) { scanf("%d",&a[i][j]); if(a[i][j]==-1) { _x=i; _y=j; map[i][j]=3; } else if(a[i][j]>0) { map[i][j]=2; } } } memset(vis, 0, sizeof(vis)); ok=false; find(_x,_y); if(ok) { puts("Ali Win"); continue; } ans=sum=0; memset(vis, 0, sizeof(vis)); for(int i=0; i<n; i++) if(!vis[i][0]) bfsfind(i,0); for(int i=0; i<n; i++) if(!vis[i][m-1]) bfsfind(i,m-1); for(int j=0; j<m; ++j) if(!vis[0][j]) bfsfind(0,j); for(int j=0; j<m; ++j) if(!vis[n-1][j]) bfsfind(n-1,j); //cout << sum << endl; if(sum%2) puts("Ali Win"); else puts("Baba Win"); } return 0; }