UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
2015-07-31 10:45
513 查看
暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的。
1.最裸的暴搜
6.420s,差点超时
2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放
0.400s
第一种剪枝
3.可以逐行(或逐列)放置。还有一个剪枝就是最多放5个,所以maxd==4还没有解,直接输出5.
0.201s
1.最裸的暴搜
6.420s,差点超时
2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放
0.400s
#include<cstdio> #include<cstring> const int maxn = 11; char G[maxn][maxn]; int maxd; int n,m; bool visi[maxn],visj[maxn],vis1[maxn<<1],vis2[maxn<<1]; bool dfs(int d,int si,int sj) { if(d == maxd){ for(int i = 0; i < n; i++) for(int j = 0; j < m; j++){ if(G[i][j] == 'X'&&!visi[i]&&!visj[j]&&!vis1[i+j]&&!vis2[i-j+10]) return false; } return true; } for(int i = si; i < n; i++){ for(int j = (i == si?sj:0); j < m; j++) if(!visi[i] || !visj[j] || !vis1[i+j]|| !vis2[i-j+10]){ bool f1 = visi[i], f2 = visj[j], f3 = vis1[i+j], f4 = vis2[i-j+10]; visi[i] = visj[j] = vis1[i+j] = vis2[i-j+10] = true; if(dfs(d+1,i,j))return true; visi[i] = f1; visj[j] = f2; vis1[i+j] = f3; vis2[i-j+10] = f4; } } return false; } int main() { int cas = 0; while(scanf("%d%d",&n,&m),n){ for(int i = 0;i < n; i++) scanf("%s",G[i]); for(maxd = 1; maxd < 5; maxd++){ memset(visi,0,sizeof(visi)); memset(visj,0,sizeof(visj)); memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); if(dfs(0,0,0))break; } printf("Case %d: %d\n",++cas,maxd); } return 0; }
第一种剪枝
3.可以逐行(或逐列)放置。还有一个剪枝就是最多放5个,所以maxd==4还没有解,直接输出5.
0.201s
#include<cstdio> #include<cstring> const int maxn = 11; char G[maxn][maxn]; int maxd; int n,m; bool visi[maxn],visj[maxn],vis1[maxn<<1],vis2[maxn<<1]; bool dfs(int d,int si) { if(d == maxd){ for(int i = 0; i < n; i++) for(int j = 0; j < m; j++){ if(G[i][j] == 'X'&&!visi[i]&&!visj[j]&&!vis1[i+j]&&!vis2[i-j+10]) return false; } return true; } for(int i = si; i < n; i++){ for(int j = 0; j < m; j++) if(!visi[i] || !visj[j] || !vis1[i+j]|| !vis2[i-j+10]){ bool f1 = visi[i], f2 = visj[j], f3 = vis1[i+j], f4 = vis2[i-j+10]; visi[i] = visj[j] = vis1[i+j] = vis2[i-j+10] = true; if(dfs(d+1,i+1))return true; visi[i] = f1; visj[j] = f2; vis1[i+j] = f3; vis2[i-j+10] = f4; } } return false; } int main() { int cas = 0; while(scanf("%d%d",&n,&m),n){ for(int i = 0;i < n; i++) scanf("%s",G[i]); for(maxd = 1; maxd < 5; maxd++){ memset(visi,0,sizeof(visi)); memset(visj,0,sizeof(visj)); memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); if(dfs(0,0))break; } printf("Case %d: %d\n",++cas,maxd); } return 0; }
相关文章推荐
- 有空学习学习
- The return types for the following stored procedures could not be detected
- html与html5
- “再回首,云遮断归途,再回首,荆棘密布...
- win10字体模糊显示不清晰怎么调整?
- 一杯香茗,一点曲,
- javascript常用正则表达式汇总
- android缓存目录
- 会场安排问题
- Maximum Product(UVa 11059)
- 通过持续Ping来检测网络质量
- .net反射详解
- 南阳oj 71 独木舟上的旅行
- 拥有主消息循环的worker线程
- Visual Studio: 暂时?绕过 fatal error C1083: Cannot open precompiled header file
- mybatis防止sql注入
- Java SE JDK 历史版本下载 Oracle 官方下载地址
- 如何把php5.3版本升级到php5.4或者php5.5
- javascript 数组去重的几种方法
- java枚举类型