【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) */
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#获取关键字附近文字算法实例