题目:

输入一个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(迭代加深搜索)的更多相关文章

  1. UVA - 11214 Guarding the Chessboard(守卫棋盘)(迭代加深搜索)

    题意:输入一个n*m棋盘(n,m<10),某些格子有标记.用最少的皇后守卫(即占据或者攻击)所有带标记的格子. 分析:因为不知道放几个皇后可以守卫所有带标记的格子,即回溯法求解时解答树的深度没有 ...

  2. UVA 529 - Addition Chains,迭代加深搜索+剪枝

    Description An addition chain for n is an integer sequence  with the following four properties: a0 = ...

  3. uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索

    迭代加深搜索 自己看的时候第一遍更本就看不懂..是非常水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的 ...

  4. UVA 1343 - The Rotation Game-[IDA*迭代加深搜索]

    解题思路: 这是紫书上的一道题,一开始笔者按照书上的思路采用状态空间搜索,想了很多办法优化可是仍然超时,时间消耗大的原因是主要是: 1)状态转移代价很大,一次需要向八个方向寻找: 2)哈希表更新频繁: ...

  5. 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 ...

  6. UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)

    暴力,和八皇后很像,用表示i+j和i-j标记主对角线,但是还是要加一些的剪枝的. 1.最裸的暴搜 6.420s,差点超时 2.之前位置放过的就没必要在放了,每次从上一次放的位置开始放 0.400s # ...

  7. UVA - 1374 Power Calculus (dfs迭代加深搜索)

    题目: 输入正整数n(1≤n≤1000),问最少需要几次乘除法可以从x得到xn ?在计算过程中x的指数应当总是正整数. 思路: dfs枚举次数深搜 注意: 1.指数如果小于0,就退出当前的搜索 2.n ...

  8. UVA 11214 Guarding the Chessboard

    题意: 皇后防御的范围是他所在横.竖.对角线,地图上的#为可以放旗子的地方.问最少放几个皇后能防守所有#. 分析: vis数组开4维,对应行.列.主对角线.副对角线 代码: #include < ...

  9. UVA - 11214 Guarding the Chessboard (可重复覆盖,DLX+IDA*)

    题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. #include ...

随机推荐

  1. P3199 [HNOI2009]最小圈 01分数规划

    裸题,第二个权值是自己点的个数.二分之后用spfa判负环就行了. 题目描述 考虑带权的有向图G=(V,E)G=(V,E)G=(V,E)以及w:E→Rw:E\rightarrow Rw:E→R,每条边e ...

  2. 4.7.4 Constructing LALR Parsing Tables

    4.7.4 Constructing LALR Parsing Tables We now introduce our last parser construction method, the LAL ...

  3. python-----自动解压并删除zip文件

    如何自动解压并删除zip? 如何解压  →  使用内置模块来实现(shutil.unpack_archive) 如何删除zip  →  使用内置模块os来实现(os.remove) 如何监测zip的出 ...

  4. [置顶][终极精简版][图解]Nginx搭建flv mp4流媒体服务器

    花了我接近3周,历经了重重问题,今日终于把流媒体服务器搞定,赶紧的写个博文以免忘记... 起初是跟着网上的一些教程来的,但是说的很不全面,一些东西也过时不用了(比如jwplayer老版本).我这次是用 ...

  5. Java多线程系列二——Thread类的方法

    Thread实现Runnable接口并实现了大量实用的方法 public static native void yield(); 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机 ...

  6. Tomcat优化和JVM分析工具

    Tomcat的常见优化和JVM常见分析工具 Tomcat的常用优化配置 (1) 内存空间: /etc/sysconfig/tomcat JAVA_OPTS="-server -Xms32g ...

  7. C#多线程,基础知识很重要

    本文通过介绍C#多线程的用法(基础玩法),附加介绍一下WinForm里边跨线程访问UI的方法 如图,就是这么一个简单的界面,每个按钮下面一个方法,分别设置文本框里边的内容,那么,开始吧! 先介绍一下W ...

  8. [C陷阱和缺陷] 第7章 可移植性缺陷

      C语言在许多不同的系统平台上都有实现.的确,使用C语言编写程序的一个首要原因就是,C程序能够方便地在不同的编程环境中移植.   不同的系统有不同的需求,因此我们应该能够预料到,机器不同则其上的C语 ...

  9. 树形DP UVA 1292 Strategic game

    题目传送门 /* 题解:选择一个点,它相邻的点都当做被选择,问最少选择多少点将所有点都被选择 树形DP:dp[i][0/1]表示当前点选或不选,如果选,相邻的点可选可不选,取最小值 */ /***** ...

  10. Git学习笔记(0)-错误汇总

    一.LF will be replaced by CRLF 1.发现问题 $ git add welcome.txt warning: LF will be replaced by CRLF in w ...