[题解] HDU 4101 Ali and Baba (BFS)
来源:互联网 发布:c语言 p 编辑:程序博客网 时间:2024/05/21 09:22
题意:两人轮流开墙,每人一次只能开一个墙(或者打宝藏),打到宝藏的人胜利。
分析:算出外面所有能敲的墙的数量,因为没人会傻到帮别人去开墙然后别人直接进去拿宝藏…再判断奇偶性,谁敲掉围绕这宝藏的那一圈墙谁就输了。
在看到这一道题目时,我再一次(恬不知耻的)觉得:(*@ο@*) 哇~,好水啊!准备直接从-1开始BFS,然后将在内部的所有点的数量记录下来,然后用总点数去减去内部点数再判断奇偶性即可得到答案。
BUT,WA WA WA使我不得不冷静下来,重新看代码…
原来是有一种情况没有考虑到。
For example
7 7
1 1 1 1 1 1 1
1 1 0 -1 0 0 1
1 0 1 1 1 0 1
1 0 1 1 1 0 1
1 0 1 1 1 0 1
1 0 0 0 0 0 1
1 1 1 1 1 1 1
这样的数据,第四行,第四个数据就无法读取到,于是乎,瞬间爆炸
那么怎么解决呢?——双BFS
双BFS的思路是这样的,将第一次从-1开始扩展得到的点全部标记(其实就是判重数组吗),然后从外往内BFS一遍,如果搜到的是没有标记过的点,入队,将这个点HP敲完;要是标记过,不入队,将这个点HP敲到剩下1滴。那么,敲掉HP的总数即为判断的依据。
并且要记得,如果第一遍搜出了图,那么说明宝藏直接和外界相连哦,那么Ali就直接赢了。
看代码↓↓↓
#include <bits/stdc++.h>using namespace std;bool flag=0;int n,m,stx,sty,sum=0,total=0;int MAP[310][310];bool pd[310][310];bool pdc[310][310];int mo[4][2]={1,0,0,1,-1,0,0,-1};struct node { int x,y;}st;queue <node> q;//懒得手写队列 X1queue <node> p;//懒得手写队列 X2void input() { int i,j; for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&MAP[i][j]); if(MAP[i][j]==-1) { st.x=i; st.y=j; } else { sum+=MAP[i][j]; } } } return;}bool bfs2() {//从外往内 int nx,ny,i,j; while(!p.empty()) {p.pop();} for(i=0;i<n;i++) { p.push(node{i,-1}); p.push(node{i,m}); } for(j=0;j<m;j++) { p.push(node{-1,j}); p.push(node{n,j}); } while(!p.empty()) { node now=p.front(); p.pop(); for(int i=0;i<=3;i++) { nx=now.x+mo[i][0]; ny=now.y+mo[i][1]; if(nx>=0 && nx<n && ny>=0 && ny<m) { if(!pdc[nx][ny]) { pdc[nx][ny]=1; if(pd[nx][ny]) { total+=MAP[nx][ny]-1; } else { total+=MAP[nx][ny]; p.push(node{nx,ny}); } } } } } if(total&1) {return 1;} return 0;}bool bfs1() {//从内往外 int nx,ny; while(!q.empty()) {q.pop();} q.push(st); pd[st.x][st.y]=1; while(!q.empty() && !flag) { node now=q.front(); q.pop(); for(int i=0;i<=3;i++) { nx=now.x+mo[i][0]; ny=now.y+mo[i][1]; if(nx>=0 && nx<n && ny>=0 && ny<m) { if(pd[nx][ny]) continue; if(MAP[nx][ny]==0) { q.push(node{nx,ny}); pd[nx][ny]=1; } else if(MAP[nx][ny]>=1) { pd[nx][ny]=1; } } else {flag=1;break;} } if(flag) {break;} } if(flag) {return 1;}//要是搜出去了,直接Ali赢 bfs2();}int main() { while(~scanf("%d%d",&n,&m)) { memset(MAP,0,sizeof(MAP)); memset(pd,0,sizeof(pd)); memset(pdc,0,sizeof(pdc)); total=0;sum=0;flag=0; input(); if(bfs1()) printf("Ali Win\n"); else printf("Baba Win\n"); } return 0;}
From:Chlience
阅读全文
1 0
- [题解] HDU 4101 Ali and Baba (BFS)
- BFS-hdu-4101-Ali and Baba
- hdu 4101 Ali and Baba(bfs,dfs)
- HDU 4101Ali and Baba (bfs)
- hdu 4101 Ali 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&dfs扫描二维点)
- hdu 4101 - Ali and Baba(搜索)
- HDU:4101 Ali and Baba(搜索+博弈)
- HDU4101:Ali and Baba(BFS)
- HDU4101 Ali and Baba (bfs+dfs+博弈)
- HDU 4101 Ali and Baba 博弈, 连通块
- 题解: HDU 1254 :推箱子 (BFS)
- [题解] HDU 3839 Ancient Messages(BFS)
- 异或实现变量交换
- Redis中Sort Set如何使用?
- Unity+Behavior Tree行为树 Behavior Designer TaskList介绍三
- Java的基本配置
- dedecms中指定输出某个栏目的信息:
- [题解] HDU 4101 Ali and Baba (BFS)
- JavaScript的数组常用方法
- JAVA封装类和Class类
- Lucene 的核心索引类
- dedecms任意页面调用栏目内容标签{dede:field.content/}的方法
- 如何使QGraphicsItem不随QGraphicsView放大缩小而改变大小
- ZooKeeper 学习 (五) 开源ZkClient操作ZooKeeper
- Android学习笔记(一)
- Android源码学习——linker(2)