您的位置:首页 > 编程语言 > Go语言

【HDU5546 2015 CCPC 南阳国赛G】【DFS】Ancient Go 棋盘围杀 优化写法O(n^2)

2015-11-02 00:32 239 查看
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
typedef long long LL;
const int Z=1e9+7;
const int N=12;
const int dy[4]={-1,0,0,1};
const int dx[4]={0,-1,1,0};
int casenum,casei;
int n,m;
char a

;
int e

;
int tim,cnt;
void dfs(int y,int x)
{
e[y][x]=1;
for(int i=0;i<4;i++)
{
int yy=y+dy[i];
int xx=x+dx[i];
if(a[yy][xx]=='.'&&e[yy][xx]!=tim){++cnt;e[yy][xx]=tim;}
if(a[yy][xx]=='o'&&e[yy][xx]==0)dfs(yy,xx);
}
}
bool check()
{
MS(e,0);
for(int i=1;i<=9;i++)
{
for(int j=1;j<=9;j++)if(a[i][j]=='o'&&e[i][j]==0)
{
++tim;
cnt=0;
dfs(i,j);
if(cnt==1)return 1;
}
}
return 0;
}
int main()
{
scanf("%d",&casenum);
for(casei=1;casei<=casenum;casei++)
{
for(int i=1;i<=9;i++)scanf("%s",a[i]+1);
if(check())printf("Case #%d: Can kill in one move!!!\n",casei);
else printf("Case #%d: Can not kill in one move!!!\n",casei);
}
return 0;
}
/*
【trick&&吐槽】
做题还是要先把每题都看下的好。
这题这么水,然而我却很晚才AC,都是因为发现得太晚了>_<

【题意】
给你一个9*9的棋盘,棋盘上有——
x(我方棋子)
o(敌方棋子)
.(空白位置)
现在问你,能否把接下来的一个'x',放到地图中的一个空白位置'.'上。
使得出现一个联通块内的'o',找不到任何一个可以扩展的联通块位置'.'

【类型】
暴力+DFS

【分析】
这题棋盘这么小。
于是我们可以直接枚举'.'填放。
更高效的是,我们枚举'o'周围的'x'填放。
然后放完'x'之后,再dfs看看这个'o'能否搜到'.'。
搜的到的话,这个放置就是失败的。
搜不到的话,这个放置就是成功的。
这题的一个优化策略是,对于每个'o'的联通块,我看其周围能探索到的'.'的个数,如果个数恰为1,那么就找到.
然而要小心重复计数。时间复杂度就可以降为O(n^2)

【时间复杂度&&优化】
O(n^2)

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 算法 ICPC