HDU4101 Ali and Baba (bfs+dfs+博弈)

2024-08-30 20:58
文章标签 bfs dfs 博弈 ali hdu4101 baba

本文主要是介绍HDU4101 Ali and Baba (bfs+dfs+博弈),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意: Ali 和Baba玩游戏,游戏是在给出的一个n*m的图中,有且仅有一个宝藏(-1)表示,图中其他位置可能是空地(0表示),也可能是石头(石头的HP用一个正数表示)。二人轮流,每次游戏开始都是Ali先手,选手可以攻击石头,每次可以让石头HP减少一。问Ali是否可以胜利。
开始时,直接BFS 宝藏能扩展的最大的面积,因为面对都是1包围的-1 ,这个是必败态。但是WA了;然后想了很久,想到,可能存在宝藏所形成的连通的块是个环形,把其他的石头包围在里面,这样,这些石头就等于是没用的了。所以不得不多写了一个BFS_ans()

#include<bits/stdc++.h>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define out(x) cout<<x<<endl;
using namespace std;
const int maxn=305;
const int inf=9999999;int n,m;
int a[maxn][maxn];
bool vis[maxn][maxn];int dir[][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool pan(P s){if(s.X>=0&&s.X<=n+1&&s.Y>=0&&s.Y<=m+1)return true;return false;
}
void bfs(int x,int y){//标记宝藏形成的连通的块cl(vis,false);queue<P> q;q.push(P(x,y));vis[x][y]=true;while(!q.empty()){P s=q.front();q.pop();for(int i=0;i<4;i++){P tmp=s;tmp.X+=dir[i][0];tmp.Y+=dir[i][1];if(pan(tmp)&&!vis[tmp.X][tmp.Y]){vis[tmp.X][tmp.Y]=true;if(a[tmp.X][tmp.Y]==0)q.push(tmp);}}}
}
bool vis1[maxn][maxn];int bfs_ans(){cl(vis1,false);queue<P> q;q.push(P(0,0));vis1[0][0]=true;int ans=0;while(!q.empty()){P s=q.front();q.pop();for(int i=0;i<4;i++){P tmp=s;tmp.X+=dir[i][0];tmp.Y+=dir[i][1];if(pan(tmp)&&!vis1[tmp.X][tmp.Y]){if(vis[tmp.X][tmp.Y]){if(a[tmp.X][tmp.Y]>1)ans+=a[tmp.X][tmp.Y]-1;}else {ans+=a[tmp.X][tmp.Y];q.push(tmp);}vis1[tmp.X][tmp.Y]=true;}}}return ans;
}bool used[maxn][maxn];
bool dfs(int x,int y){//查找是否存在一个直达的路径if(x==1||x==n||y==1||y==m){return true;}for(int i=0;i<4;i++){int xx=x+dir[i][0];int yy=y+dir[i][1];if(pan(P(xx,yy))&&!used[xx][yy]&&a[xx][yy]==0){used[xx][yy]=true;if(dfs(xx,yy))return true;//used[xx][yy]=false;}}return false;
}int main(){while(~scanf("%d%d",&n,&m)){int si,sj;cl(a,0);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);if(a[i][j]==-1){si=i;sj=j;}}}if(si==1||si==n||sj==1||sj==m){puts("Ali Win");continue;}cl(used,0);if(dfs(si,sj)){puts("Ali Win");continue;}bfs(si,sj);//printf("===%d\n",bfs_ans());if(bfs_ans()&1){puts("Ali Win");}else {puts("Baba Win");}}return 0;
}
/*
4 4
1 1 1 1
1 1 0 1
1 1 -1 1
1 1 1 1
3 3
1 1 1
1 -1 1
1 1 1
4 4
1 1 0 1
1 1 0 1
1 1 -1 1
1 1 1  1
*/

这篇关于HDU4101 Ali and Baba (bfs+dfs+博弈)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1121917

相关文章

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

poj2505(典型博弈)

题意:n = 1,输入一个k,每一次n可以乘以[2,9]中的任何一个数字,两个玩家轮流操作,谁先使得n >= k就胜出 这道题目感觉还不错,自己做了好久都没做出来,然后看了解题才理解的。 解题思路:能进入必败态的状态时必胜态,只能到达胜态的状态为必败态,当n >= K是必败态,[ceil(k/9.0),k-1]是必胜态, [ceil(ceil(k/9.0)/2.0),ceil(k/9.

hdu3389(阶梯博弈变形)

题意:有n个盒子,编号1----n,每个盒子内有一些小球(可以为空),选择一个盒子A,将A中的若干个球移到B中,满足条件B  < A;(A+B)%2=1;(A+B)%3=0 这是阶梯博弈的变形。 先介绍下阶梯博弈: 在一个阶梯有若干层,每层上放着一些小球,两名选手轮流选择一层上的若干(不能为0)小球从上往下移动,最后一次移动的胜出(最终状态小球都在地面上) 如上图所示,小球数目依次为

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

poj 3050 dfs + set的妙用

题意: 给一个5x5的矩阵,求由多少个由连续6个元素组成的不一样的字符的个数。 解析: dfs + set去重搞定。 代码: #include <iostream>#include <cstdio>#include <set>#include <cstdlib>#include <algorithm>#include <cstring>#include <cm

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

ural 1149. Sinus Dances dfs

1149. Sinus Dances Time limit: 1.0 second Memory limit: 64 MB Let  An = sin(1–sin(2+sin(3–sin(4+…sin( n))…) Let  Sn = (…( A 1+ n) A 2+ n–1) A 3+…+2) An+1 For given  N print  SN Input One

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访