hdu 4101(bfs+博弈)
生活随笔
收集整理的這篇文章主要介紹了
hdu 4101(bfs+博弈)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題意:題目的意思就是說兩個人輪流玩游戲,給你一張地圖,這個地圖中間有一點-1代表寶藏,Ali and Baba輪流走
路,如果某一個人能夠直接走到寶藏的話,那么他就贏了。地圖上其它的點0代表空地,數(shù)字代表當(dāng)前地點的石子當(dāng)
某一人拿石子的時候,他只能拿走一顆。問你誰最后能拿到寶藏;
解題思路:寶藏位于-1位置,如果能夠直接找一條通路的話,那么肯定是Ali贏,這一步顯然可以用bfs,只要出了邊界的就有同路。如果沒有的話,那么肯定這一條路徑A被石頭給圍住了。那么我們首先把從寶藏位置引伸出來的路周圍的所有石頭標(biāo)記了(這一步可以在第一次找通路的時候完成),接下來,如果這條路被包圍的石頭數(shù)都為1了,那么接下來取石頭的人就會輸,因為被包圍的石頭打通了。。所以直接計算出兩人總共取石頭的數(shù)量(不是全部取完,而是留下路徑周圍被1一個石頭所包圍),剩下的就是判斷奇偶性就可以知道誰贏誰輸了。。這道題確實轉(zhuǎn)化得非常巧妙
AC:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std;const int maxn = 310; struct node {int x,y; }; int n,m,map[maxn][maxn],ans; int dx,dy,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; bool has[maxn][maxn],vis[maxn][maxn];bool bfs1() {queue<node> q;node cur,nxt;cur.x = dx, cur.y = dy;q.push(cur);while(!q.empty()){cur = q.front();q.pop();if(cur.x < 1 || cur.x > n || cur.y < 1 || cur.y > m) return true;for(int k = 0; k < 4; k++){int i = cur.x + dir[k][0];int j = cur.y + dir[k][1];if(map[i][j] == 0){map[i][j] = -1;nxt.x = i, nxt.y = j;q.push(nxt);}else if(map[i][j] > 0) has[i][j] = true;}}return false; }void bfs2() {queue<node> q;node cur,nxt;cur.x = 0, cur.y = 0;vis[0][0] = true;q.push(cur);while(!q.empty()){cur = q.front();q.pop();for(int k = 0; k < 4; k++){int i = cur.x + dir[k][0];int j = cur.y + dir[k][1];if(i < 0 || i > n + 1 || j < 0 || j > m + 1 || vis[i][j]) continue;vis[i][j] = true;if(has[i][j] == false){ans += map[i][j];nxt.x = i, nxt.y = j;q.push(nxt);}else ans += map[i][j] - 1;}} }int main() {while(scanf("%d%d",&n,&m)!=EOF){memset(map,0,sizeof(map));memset(has,false,sizeof(has));memset(vis,false,sizeof(vis));for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++){scanf("%d",&map[i][j]);if(map[i][j] == -1)dx = i, dy = j;}if(bfs1()){printf("Ali Win\n");continue;}ans = 0;bfs2();if(ans & 1)printf("Ali Win\n");else printf("Baba Win\n");}return 0; }
總結(jié)
以上是生活随笔為你收集整理的hdu 4101(bfs+博弈)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MD5和RSA
- 下一篇: 创业者眼中的小程序:某个岗位工资会翻番