BFS-hdu-4101-Ali and Baba
来源:互联网 发布:mac rar 编辑:程序博客网 时间:2024/05/21 18:31
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4101
题目大意:
给一个矩阵,0表示空的可走,-1宝藏的位置(只有一个),其余的正整数表示该位置石头数。甲乙两个人,轮流玩游戏。甲先玩,谁先从外面通过空路径到达了宝藏的位置(不能经过石头),谁就获胜。如果不能直接到达宝藏位置,可以从外面通过空到某个位置,拿走该位置上的一个石头,如果该位置没有石头则变成空的可走。
解题思路:
不错的BFS。
首先如果甲能一步到达宝藏位置,则甲获胜。
否则,一定有一个环包围着宝藏,则甲肯定不能先捅破这个环,不然乙一步就赢了。所以它尽可能的拿掉环外的石头,同理对于乙来说,也是尽可能的拿掉外面的石头,不能把环打破。
所以只用统计外面石头总数以及环上每个位置留一个石头后的和即可。
如果是奇数,说明甲恰好把最后一个环外的石头拿掉,此时乙必破环。甲胜,否则乙胜。
bfs1() //从宝藏位置从内往外扫描,把该环标记。
bfs2() //从边框bfs,如果走到了边界 +(hp-1) 否则为外面的点 +(hp)
注意:
6 7
1 1 1 1 1 1 1
1 0 0 0 0 0 1
1 0 3 5 1 1 1
1 0 -1 4 0 1 1
1 0 1 0 0 1 1
1 1 1 1 1 1 1
ans=16 不是22
这组测试数据 计数的时候是不包括3,5的,因为环已经包括了。(wa了一上午)不能直接统计空的,非空的也要标记,只不过不放到队列中而已,要换个姿势。
还有要注意这组测试数据:
7 7
1 1 1 1 1 1 1
1 1 0 0 0 0 1
1 0 0 1 0 0 1
1 0 1 1 1 0 1
1 0 0 1 0 0 1
1 0 0 -1 0 0 1
1 1 1 1 1 1 1
环内有有数。
代码:
#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<string>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#define eps 1e-6#define INF 0x1f1f1f1f#define PI acos(-1.0)#define ll __int64#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;/*freopen("data.in","r",stdin);freopen("data.out","w",stdout);*/#define Maxn 320int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};int mm[Maxn][Maxn],n,m;bool vis[Maxn][Maxn];bool vis2[Maxn][Maxn];struct Node{ int x,y;};Node s;bool isbor(int x,int y) //是否为边界{ if(x==1||y==1||x==n||y==m) return true; return false;}bool iscan(int x,int y) //是否在{ if(x<1||x>n||y<1||y>m) return false; return true;}bool bfs1(){ memset(vis,false,sizeof(vis)); queue<Node>myq; myq.push(s); vis[s.x][s.y]=true; if(isbor(s.x,s.y)) return true; while(!myq.empty()) { Node cur=myq.front(); //printf(":%d %d\n",cur.x,cur.y); myq.pop(); for(int i=0;i<4;i++) { int xx=cur.x+dir[i][0],yy=cur.y+dir[i][1]; if(!iscan(xx,yy)) continue; if(isbor(xx,yy)&&mm[xx][yy]==0) //空位置 伸到了外面 return true; if(vis[xx][yy]) continue; vis[xx][yy]=true; if(mm[xx][yy]) //这也标记下 防止内部的干扰 continue; Node tmp; tmp.x=xx,tmp.y=yy; myq.push(tmp); //printf("push:%d %d\n",tmp.x,tmp.y); } } return false;}int bfs2(){ int res=0; queue<Node>myq; myq.push(s); vis2[s.x][s.y]=true; //res+=mm[s.x][s.y]; while(!myq.empty()) { Node cur=myq.front(); myq.pop(); for(int i=0;i<4;i++) { int x=cur.x+dir[i][0],y=cur.y+dir[i][1]; // printf("x:%d y:%d\n",x,y); if(!iscan(x,y)||vis2[x][y]) //是否被访问了 continue; vis2[x][y]=true; if(vis[x][y]) //如果是内边界 { res+=(mm[x][y]-1); //直接+(hp-1) continue; } //其它的点 +hp Node tmp; tmp.x=x,tmp.y=y; res+=mm[x][y]; myq.push(tmp); } } return res;}int main(){ while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&mm[i][j]); if(mm[i][j]==-1) s.x=i,s.y=j; } if(bfs1()) { printf("Ali Win\n"); continue; } /* putchar('\n'); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%d ",vis[i][j]); putchar('\n'); }*/ int ans=0; memset(vis2,false,sizeof(vis2)); //统计外围是否被访问了 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(isbor(i,j)) //从边界开始扫 { if(vis2[i][j]) //之前已经扫过了 continue; vis2[i][j]=true; if(vis[i][j]) //碰到了边界 直接+(hp-1) ans+=(mm[i][j]-1); else { ans+=mm[i][j]; //不是边界 加上然后继续扫 s.x=i,s.y=j; ans+=bfs2(); } } } // printf(":%d\n",ans); if(ans&1) printf("Ali Win\n"); else printf("Baba Win\n"); } return 0;}
- BFS-hdu-4101-Ali and Baba
- hdu 4101 Ali and Baba(bfs,dfs)
- HDU 4101Ali and Baba (bfs)
- HDU 4101 Ali and Baba
- HDU 4101 Ali and Baba
- HDU 4101 Ali and Baba
- HDU 4101 Ali and Baba
- hdu 4101 Ali and Baba (bfs+严密思维)
- hdu 4101 Ali and Baba【BFS好题】
- [题解] HDU 4101 Ali and Baba (BFS)
- hdu 4101 - Ali and Baba(搜索)
- HDU:4101 Ali and Baba(搜索+博弈)
- HDU4101:Ali and Baba(BFS)
- !HDU 4101 Ali and Baba-博弈-(bfs&dfs扫描二维点)
- HDU 4101 Ali and Baba 博弈, 连通块
- HDU4101 Ali and Baba (bfs+dfs+博弈)
- Ali
- ali
- Struts2 类型转换流程
- XMPP协议的基础知识
- Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)
- Ubuntu快捷键 终端快捷键
- Java中的泛型方法
- BFS-hdu-4101-Ali and Baba
- hadoop博客
- SPOJ 1812. Longest Common Substring II(后缀自动机)
- 销售必知:销售流程
- u-boot-2012.10移植全记录(基于s3c2440)
- 短训学习录(一)——喜欢简单的学生生活
- Android---AlarmManager(全局定时器/闹钟)指定时长或以周期形式执行某项操作
- C语言堆空间的生成与释放
- PHP开发工程师面试题2