HDU 4101 有意思的广搜

题意:在一个n*n的矩阵内,两个人想要找到一个 “ 宝藏 “,用-1表示。其中有空地,每回合可任意穿梭,用0表示,有怪物,无法直接穿过,需要杀死,每回合砍1 HP,等于0时死亡,由两人从最外围开始,每人一回合行动,问谁能获得 ”  宝藏  “ 。

题解: 看似博弈 ,同样可以从必胜状态考虑,当宝藏周围只剩下最后一圈血量为1的怪物时,  谁先打死那个怪物,谁就输了。

两人都不愿意杀死那只堵着宝藏门的第一只怪 ,所以两人的状态就是一直在砍门外面的怪,你一刀我一刀。所以我们只需要知道除了最后一圈怪,门外的怪物血量之和为奇数还是偶数就可以判断是先者还是后者赢。

先从起点开始广搜,找到那最内围的一圈怪物,将其标记为1

再从外围开始搜,搜到外围怪物,num += 怪物血量。  搜到内围怪我  num += (怪物血量 - 1),留一个怪看门

代码 :

#include<stdio.h>

#include<iostream>

#include<queue>

using namespace std;

int mark_bfs[333][333], mark_bfs2[333][333], map[333][333], flag, num, n, m;

int dx[4] = {1, -1, 0, 0};

int dy[4] = {0, 0, 1, -1};

struct Node

{

int x, y;

}st;

void bfs(Node st)

{

queue<Node> p;

p.push(st);

mark_bfs[st.x][st.y] = 1;

Node v, vn;

while(!p.empty())

{

vn = p.front();

p.pop();

for(int i =0; i < 4; i++)

{

v.x = vn.x + dx[i];

v.y = vn.y + dy[i];

if((v.x == n - 1 || v.x == 0 || v.y == m - 1 || v.y == 0)&&(map[v.x][v.y] == 0)) { flag = 1; return; }

if(mark_bfs[v.x][v.y])  continue;

if(map[v.x][v.y] == 0)

p.push(v);

mark_bfs[v.x][v.y] = 1;

}

}

}

void bfs2(Node st)

{

queue<Node> p;

p.push(st);

if(mark_bfs2[st.x][st.y])   return;

mark_bfs2[st.x][st.y] = 1;

Node v, vn;

while(!p.empty())

{

vn = p.front();

p.pop();

num += map[vn.x][vn.y];

for(int i = 0 ;i < 4; i++)

{

v.x = vn.x + dx[i];

v.y = vn.y + dy[i];

if(v.x >= n || v.x < 0 || v.y >= m || v.y < 0)  continue;

if(mark_bfs2[v.x][v.y])  continue;

if(mark_bfs[v.x][v.y])   {    num += (map[v.x][v.y] - 1);  mark_bfs2[v.x][v.y] = 1; continue; }

mark_bfs2[v.x][v.y] = 1;

p.push(v);

}

}

}

int main()

{

while(scanf("%d%d", &n, &m)!=EOF)

{

memset(mark_bfs, 0, sizeof(mark_bfs));

memset(mark_bfs2, 0, sizeof(mark_bfs2));

for(int i = 0; i < n; i ++)

{

for(int j = 0; j < m; j ++)

{

scanf("%d", &map[i][j]);

if(map[i][j] == -1)

{

st.x = i;

st.y = j;

}

}

}

flag = 0;

num = 0;

bfs(st);

if(flag)  { printf("Ali Win\n"); continue;}

for(int i = 0; i < m; i++)

{

st.x = 0;

st.y = i;

bfs2(st);

st.x = n - 1;

st.y = i;

bfs2(st);

}

for(int i = 0; i < n; i++)

{

st.x = i;

st.y = 0;

bfs2(st);

st.x = i;

st.y = m - 1;

bfs2(st);

}

if(num % 2) printf("Ali Win\n");

else printf("Baba Win\n");

}

}

时间: 2024-10-09 03:16:46

HDU 4101 有意思的广搜的相关文章

HDU 1253 (简单三维广搜) 胜利大逃亡

奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 9 struct Poin

HDU 1240 (简单三维广搜) Asteroids!

给出一个三维的迷宫以及起点和终点,求能否到大终点,若果能输出最短步数 三维的问题无非就是变成了6个搜索方向 最后强调一下xyz的顺序,从输入数据来看,读入的顺序是map[z][x][y] 总之,这是很基础的一道题 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <algorithm

HDU ACM 1495 非常可乐(广搜BFS)

非常可乐 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) : 42   Accepted Submission(s) : 21 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却

hdu 2209 状态压缩广搜

思路:    20张牌     有1>>20中情况        用二进制标记,  这道题的关键地方就是怎样无翻牌     这里用到位运算   1^x    若x为0  则为1   否则为0  这里正好用到翻牌     对前两张和后两张  都可以和3(11)进行异或运算     对中间的和7(111) 进行异或运算 #include<stdio.h> #include<queue> #include<string.h> #include<iostrea

hdu 1072 广搜

广搜,用到优先队列,跟hdu1026差不多.但须注意几个问题: 1.可以往回走,由于可以重设时间,有时需要拐弯去“加油”,但可重设时间的结点不能在让它有机会被重走,不然就进入死循环了. 2.队列每次弹出的都是用时最少的,需要自定义排序 #include <iostream> #include <queue> using namespace std; int map[9][9]; int n,m; int dir[4][2]={0,1, 1,0, -1,0, 0,-1}; struc

HDU 3085 Nightmare Ⅱ (双向广搜)

题意:有M,G两人和鬼魂(Z)在n*m的方格内,M每秒走3步,G每秒走一步,鬼魂每秒走2步,问是否能 不遇到鬼魂下两人相遇,鬼魂可以穿墙(X),人不可以.初始鬼魂有2个. #include<stdio.h> #include<string.h> #include<string> #include<queue> #include<map> #include<iostream> #include<algorithm> #def

HDU 1195 Open the Lock (双向广搜)

题意:给你初始4个数字和目标4个数字,问是否能由初始经过变换到目标数字: 变换规则:每个数字可以加1(9+1=1)或减1(1-1=9),或交换相邻的数字(最左和最右不是相邻的). 双向广搜:分别对初始和目标数字进行广搜,vis数组用1和2标记两种已搜索的数字,用mp数组记录状态的步数. 当从前往后搜可以到达2或从后往前搜可以到达1状态则就可以了... #include<stdio.h> #include<string.h> #include<string> #inclu

HDU 1401 Solitaire (双向广搜)

题意:在二维8*8的方格,给定4个初始点和4个最终点,问在8步内是否能从初始点走到最终点, 规则:每个点能上下左右移动,若4个方向已经有点则可以跳到下一个点. 双向广搜:同时对初始点和最终点广搜4步,对每一步记录状态,初始点为'1',最终点为'2', 若在限定时间内初始点的状态能到达'2',或最终点的状态能到达'1',则为YES!要记得排序.. #include<stdio.h> #include<string.h> #include<queue> #include&l

hdu 1242:Rescue(BFS广搜 + 优先队列)

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 14   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Angel was caught by the MOLIGPY