首页 > 其他分享 >hdu 4101(bfs+博弈)

hdu 4101(bfs+博弈)

时间:2023-05-29 22:34:56浏览次数:42  
标签:bfs hdu nxt cur map int 4101 vis maxn


题意:题目的意思就是说两个人轮流玩游戏,给你一张地图,这个地图中间有一点-1代表宝藏,Ali and Baba轮流走

路,如果某一个人能够直接走到宝藏的话,那么他就赢了。地图上其它的点0代表空地,数字代表当前地点的石子当

某一人拿石子的时候,他只能拿走一颗。问你谁最后能拿到宝藏;

解题思路:宝藏位于-1位置,如果能够直接找一条通路的话,那么肯定是Ali赢,这一步显然可以用bfs,只要出了边界的就有同路。如果没有的话,那么肯定这一条路径A被石头给围住了。那么我们首先把从宝藏位置引伸出来的路周围的所有石头标记了(这一步可以在第一次找通路的时候完成),接下来,如果这条路被包围的石头数都为1了,那么接下来取石头的人就会输,因为被包围的石头打通了。。所以直接计算出两人总共取石头的数量(不是全部取完,而是留下路径周围被1一个石头所包围),剩下的就是判断奇偶性就可以知道谁赢谁输了。。这道题确实转化得非常巧妙


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;
}




标签:bfs,hdu,nxt,cur,map,int,4101,vis,maxn
From: https://blog.51cto.com/u_16143128/6374328

相关文章

  • hdu 1510
    WhiteRectanglesTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)ProblemDescriptionYouaregivenachessboardmadeupofNsquaresbyNsquareswithequalsize.Someofthesquaresarecoloredblack,andthe......
  • hdu 2821
    题意:n*m的格子上有一些方块放在某些格子上,一个格子可能有几个方块,用'a'-'z'来表示方块数量。初始的时候可以选择任意空地作为Pusher初始点,Pusher选择一个方向,然后向这个方向前进直到遇到有方块的格子,Pusher把这个格子的方块清除一个,并把它向前推一格(向前不能出界),如果前面一格有方......
  • hdu 1534(差分约束)
    题意:安排计划,有4种约束方式,给出你这些时间的n个约束..如果计划是可行的,求出每一件事发生的最早时间..否则输出“impossible”..①.FAFaba要在b完成后完成..②.FASaba要在b开始前完成..③.SASaba要在b开始前开始..④.SAFaba要在b结束前开......
  • hdu 1532(最大流)
    解题思路:这是一道典型的模板题,直接套用EK算法即可。。。我感觉最大流的本质就是能否找到一个从源点到汇点的增广路径,并将其最小的边作为增加值,沿着增广路上的边进行更新。AC:#include<iostream>#include<cstdio>#include<cstring>#include<queue>usingnamespacestd;consti......
  • hdu 5074(简单dp)
    HatsuneMikuTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:262144/262144K(Java/Others)ProblemDescriptionHatsuneMikuisapopularvirtualsinger.ItisverypopularinbothJapanandChina.Basicallyitisacomputersoftwarethata......
  • 005 BFS_广度优先搜索
    核心就是利用队列Q:如何区分下一层?A:将当前队列中的所有节点进形扩散框架//计算从起点start到终点target的最近距离intBFS(Nodestart,Nodetarget){Queue<Node>q;//核心数据结构Set<Node>visited;//避免走回头路q.offer(start);//将起点......
  • hdu 3303(线段树+抽屉原理)
    解题思路:这题利用了抽屉原理,即1-M之间的所有数与M+1的模都不相同。那么可以利用它将要查找所有区间分成[1,Y-1],[Y,2*Y-1],[2*Y,3*Y-1].........一直下去,直到所有的区间都被找一遍,然后就是保存最小的模即可。。。这样就肯定要找每个区间的最小的模,实际上这里可以利用线段树去找,只需......
  • hdu 4417(树状数组+离线算法)
    解题思路:这道题要求某区间内比h小的个数,其实这里可以类似于树状数组求逆序数那样。关键是如何转换成树状数组的模型,这才是本题的难点。我们首先分析,如果知道h在该区间的哪个位置,那么剩下的就很好做了。我们还可以发现,如果找到了当前的比h小的所有点(大于的点我们先忽略掉),那么我们就......
  • hdu 3681(bfs+dfs+状态压缩)
    解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑。这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说,假设从u->v,我们只需要知道最短路径是多少就可以了,至于是怎么走的,中间绕过了多少个'D'都不是我们关心的......
  • hdu 4012(bfs+位压缩)
    思路:每次涂色以后必有一个格子的颜色是最终的颜色,否则这次涂色根本没意义,所以我们把每次涂色后哪些格子成为最终颜色的所有可能都入队,入队的元素是一个struct包含步数和最终颜色已确定的木块集合,这个集合必须用整数表示,所以用到状态压缩,因为最多只有16个格子,所以用16位的二进制来表......