Description
Kid和新一开始玩一个有趣的游戏。游戏规则是这样的:在一个n*m棋盘中,某个位置有一颗棋子,并且有些位置是不能走的。现在两个人轮流操作,每次可以将棋子向上下左右的格子里走一格,不能走出边界。若一方不能行动,或者走到了已经走过的格子,则算失败。
现在给出棋盘的初始状态,柯南先行。请判断当双方均用最优策略时,柯南是否可以获胜。
Input
数据有多组。
第一行为两个数n, m (2 <= n, m <= 5)。代表棋盘有n行m列。
接下来有n行,每行m个字符,代表棋盘的初始状态。其中’.’代表可行区域,’x’代表不能走的区域,’S’代表棋子的初始位置。
Output
对每组数据,若柯南可以获胜,则输出”Yes”;否则输出”No”。
Sample Input
3 3
Sx.
.x.
...
Sample Output
No
#include <cstdio>
#include <cstring>
#include <iostream>
#define Maxn 6
using namespace std;
char map[Maxn][Maxn];
int m,n;
int mark[Maxn][Maxn];
int const dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
inline bool check(int x, int y)
{
return x >= 0 && x < n && y >= 0 && y < m && map[x][y] == '.';
}
int dfs(int x,int y)
{
mark[x][y]=1;
int tx,ty;
bool flag=0;
for(int i=0;i<4;i++)
{
tx=x+dir[i][0];
ty=y+dir[i][1];
if(check(tx,ty) && !mark[tx][ty])
flag|=!dfs(tx,ty);
}
mark[x][y]=0;
return flag;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n==0) break;
for(int i=0;i<n;i++)
scanf("%s",map[i]);
memset(mark, 0, sizeof(mark));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j]=='S')
{
if(dfs(i,j)) printf("Yes\n");
else printf("No\n");
goto skip;
}
}
}
skip:;
}
return 0;
}
大致思路:从柯南开始,每次对周围进行搜索,每次将flag进行取反操作,表示柯南与基德的不同回合。如果dfs到了一条flag true的路径,则输出yes。