题意:在一个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");
}
}