题意:能不能黑棋只用下一次就可以围住一块白棋
思路:用DFS,搜索每个连通的白棋块,如果连通的白棋块外面有两个以上的出口的话,那么这一块白棋就不行,从下一个(块)白棋开始搜索;网上有的做法是开两个数组,用来标记'.'和‘o'(方便初始化'.',走过的‘o’不行就没有必要走第二次),我没有那么做,而是选择每次找完一个白棋之后将标记初始化一次,这么做会做到重复的情况,但是提交上去0ms,应该是数据太水了吧,其他的解释在代码上面
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
char Map[10][10];
int book[10][10];
int MOVE[10][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}};
int n,m;
int vis;
int flag;
int cnt;
void dfs(int x,int y)
{
if(vis)
return ;
int nx,ny;
for(int i=1;i<=4;i++)
{
nx=x+MOVE[i][0];
ny=y+MOVE[i][1];
if(nx<1||nx>9||ny<1||ny>9)
continue;
else
{
if(Map[nx][ny]=='.'&&!book[nx][ny])//不能是相同的出口
{
cnt++;
if(cnt>1)
{
vis=1;
return ;//如果找到了两个出口直接跳出
}
book[nx][ny]=1;
dfs(x,y);
}
else
if(Map[nx][ny]=='o'&&!book[nx][ny])
{
book[nx][ny]=1;
dfs(nx,ny);
}
}
}
return ;
}
int main()
{
int t;
scanf("%d",&t);
for(int k=1;k<=t;k++)
{
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
scanf(" %c",&Map[i][j]);
}
}
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)
{
memset(book,0,sizeof(book));//初始化标记
cnt=0;
flag=0;
vis=0;
if(Map[i][j]=='o')
{
book[i][j]=1;
dfs(i,j);
}
if(cnt==1)
{
flag=1;
//printf("%d %d\n",i,j);//输出调试
break;
}
}
if(flag)
break;
}
printf("Case #%d: ",k);
if(flag==1)
printf("Can kill in one move!!!\n");
else
printf("Can not kill in one move!!!\n");
}
return 0;
}