UVA - 11214 Guarding the Chessboard(迭代加深搜索)
题目:
输入一个n*m的棋盘(n,m<10),某些格子有标记,用最少的皇后守卫(即占据或攻击)所有的标记的格子。输出皇后的个数。
思路:
一开始没有想到用迭代加深搜索,直接dfs结果还没写完就发现这样要枚举的量太大了……于是换用迭代加深搜索。对于每个格子有四个方向可以用i,j,i+j,i+j+maxn(下标要是正的)表示,当cur等于枚举的答案maxd就判断是不是所有的标记都被攻击了。
另外如果这个格子放上了皇后,那该皇后所在行的后边的格子就没必要枚举了,直接跳到下一行的开头就可以了。
将二维数组线性表示的代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
char mp[maxn][maxn];
int vis[][maxn*];
int n,m,maxd; bool isok(){//判断所有的标记是不是都已经被攻击
for(int i=; i<n; i++){
for(int j=; j<m; j++){
if(mp[i][j]=='X' && !vis[][i] && !vis[][j] && !vis[][i+j] && !vis[][i-j+maxn]){
return false;
}
}
}
return true;
} bool dfs(int now, int cur){
if(cur==maxd){
return isok() ? true : false;
} for(int k=now; k<n*m; k++){
int i = k/n,j = k%m;
vis[][i]++; vis[][j]++; vis[][i+j]++; vis[][i-j+maxn]++;//对四个方向进行标记
if(dfs((i+)*m,cur+)){
return true;
}
vis[][i]--;vis[][j]--;vis[][i+j]--;vis[][i-j+maxn]--;//恢复四个方向dfs之前的状态
}
return false;
} int main(){
//FRE();
int kase = ;
while(scanf("%d",&n) && n){
scanf("%d",&m);
getchar();
for(int i=; i<n; i++){
gets(mp[i]);
}
memset(vis,,sizeof(vis));
for(maxd = ;; maxd++){
if(dfs(,)){
break;
}
}
printf("Case %d: %d\n",++kase,maxd);
}
return ;
}
正常二维数组表示代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
char mp[maxn][maxn];
int vis[][maxn*];
int n,m,maxd; bool isok(){//判断所有的标记是不是都已经被攻击
for(int i=; i<n; i++){
for(int j=; j<m; j++){
if(mp[i][j]=='X' && !vis[][i] && !vis[][j] && !vis[][i+j] && !vis[][i-j+maxn]){
return false;
}
}
}
return true;
} bool dfs(int x,int y, int cur){
if(cur==maxd){
return isok() ? true : false;
} for(int i=x; i<n; i++){
for(int j=y; j<m; j++){
vis[][i]++; vis[][j]++; vis[][i+j]++; vis[][i-j+maxn]++;//对四个方向进行标记
if(dfs(i+,,cur+)){//这一行后边的都不用遍历了,直接跳到下一行的开头就可以了
return true;
}
vis[][i]--;vis[][j]--;vis[][i+j]--;vis[][i-j+maxn]--;//恢复四个方向dfs之前的状态
}
}
return false;
} int main(){
//FRE();
int kase = ;
while(scanf("%d",&n) && n){
scanf("%d",&m);
getchar();
for(int i=; i<n; i++){
gets(mp[i]);
} for(maxd = ;; maxd++){
memset(vis,,sizeof(vis));
if(dfs(,,)){
break;
}
}
printf("Case %d: %d\n",++kase,maxd);
}
return ;
}
UVA - 11214 Guarding the Chessboard(迭代加深搜索)的更多相关文章
- UVA - 11214 Guarding the Chessboard(守卫棋盘)(迭代加深搜索)
题意:输入一个n*m棋盘(n,m<10),某些格子有标记.用最少的皇后守卫(即占据或者攻击)所有带标记的格子. 分析:因为不知道放几个皇后可以守卫所有带标记的格子,即回溯法求解时解答树的深度没有 ...
- UVA 529 - Addition Chains,迭代加深搜索+剪枝
Description An addition chain for n is an integer sequence with the following four properties: a0 = ...
- uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索
迭代加深搜索 自己看的时候第一遍更本就看不懂..是非常水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的 ...
- UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]
解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...
- UVA 11212 Editing a Book [迭代加深搜索IDA*]
11212 Editing a Book You have n equal-length paragraphs numbered 1 to n. Now you want to arrange the ...
- UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的. 1.最裸的暴搜 6.420s,差点超时 2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放 0.400s # ...
- UVA - 1374 Power Calculus (dfs迭代加深搜索)
题目: 输入正整数n(1≤n≤1000),问最少需要几次乘除法可以从x得到xn ?在计算过程中x的指数应当总是正整数. 思路: dfs枚举次数深搜 注意: 1.指数如果小于0,就退出当前的搜索 2.n ...
- UVA 11214 Guarding the Chessboard
题意: 皇后防御的范围是他所在横.竖.对角线,地图上的#为可以放旗子的地方.问最少放几个皇后能防守所有#. 分析: vis数组开4维,对应行.列.主对角线.副对角线 代码: #include < ...
- UVA - 11214 Guarding the Chessboard (可重复覆盖,DLX+IDA*)
题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. #include ...
随机推荐
- HDU 5773The All-purpose Zero
The All-purpose Zero Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- Spring 框架学习 —— 容器
容器是 Spring 框架的核心.Spring 容器使用 DI(依赖注入)机制管理构成应用的组件(类),所谓 DI,也即是其能够创建相互协作的组件(类)之间的关联(依赖). 1. 应用上下文(Appl ...
- Flask开启多线程、多进程
一.参数 app.run()中可以接受两个参数,分别是threaded和processes,用于开启线程支持和进程支持. 二.参数说明 1.threaded : 多线程支持,默认为False,即不开启 ...
- 移动前端第二弹:善用meta
前言 在移动前端第一弹:viewport详解中,我们讲了viewport,那是一个关于meta的故事.这次我们会就将meta这个故事讲得更广阔.更有意思一些. 写过HTML的童鞋,应该都对这个不陌生, ...
- UEditor动态添加图片访问路径前缀
在使用UEditor上传图片时发现上传图片后在编辑器中不能显示上传的图片,在这里是需要在jsp/config.json中设置图片访问路径前缀,即项目的根路径,在config.json只能填写字符串的配 ...
- Enum类的非一般用法汇总(工作中遇到时持续更新)
1. 每个枚举实例定义一套自己的方法示例: 1 @AllArgsConstructor 2 public enum BroadcastTypeEnum { 3 ALL(0, "全站&quo ...
- 符号修饰与函数签名、extern “C”(转载)
转自:http://www.cnblogs.com/monotone/archive/2012/11/16/2773772.html 参考资料: <程序员的自我修养>3.5.3以及3.5. ...
- bzoj 4806: 炮【dp】
同1801 注意到一行只能放012个炮,我们只需要知道列的状态,不用状压行 所以设f[i][j][k]表示前i行有j列有1个炮,有k列有2个炮的方案数 然后分情况讨论转移就行了 #include< ...
- [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(3)上传 App 预览和屏幕快照
请上传至多三个 App 预览和至多十张屏幕快照.如果您的 App 在不同设备尺寸和本地化内容间都相同,仅提供所要求的最高分辨率的屏幕快照即可. 对于 iPhone,必须提供用于 5.5 英寸设备(iP ...
- 个人微信号二次开发SDK协议,个人微信号二次开发api接口
通过这个API接口可以做什么? 通过我们提供的API接口您可以开发: 工作手机(如:X创,X码,XX管家等) 微信群讲课软件(如:讲课X师,一起X堂等) 微信社群管理软件(如:小X管家,微X助手等) ...