博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
阅读量:5068 次
发布时间:2019-06-12

本文共 2822 字,大约阅读时间需要 9 分钟。

暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的。

 

1.最裸的暴搜

6.420s,差点超时

2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放

0.400s

#include
#include
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
#include
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;}

 

转载于:https://www.cnblogs.com/jerryRey/p/4691532.html

你可能感兴趣的文章
Node.js——require加载规则
查看>>
前端模块管理器简介
查看>>
maven 国内镜像
查看>>
HttpReceiveRequestEntityBody 使用应注意的地方
查看>>
CentOS Linux iptables 防火墙
查看>>
Android AsyncTask 的实现及 cancel 方式
查看>>
李超线段树学习笔记
查看>>
java swing 按钮事件触发两次或者多次
查看>>
论演员的自我修养2
查看>>
常用算法大全-贪婪算法
查看>>
Apache Commons CLI 开发命令行工具示例
查看>>
Laravel的生命周期
查看>>
自己编写php框架(一)
查看>>
优化MySchool数据库设计
查看>>
Flink - Checkpoint
查看>>
Apache Kafka源码分析 – Controller
查看>>
查看eclipse ADT SDK JDK版本号
查看>>
保龄球计分
查看>>
在MySql中实现MemberShip的权限管理
查看>>
vim: vs sp 调整窗口高度和宽度
查看>>