题意:输入一个n*m棋盘(n,m<10),某些格子有标记。用最少的皇后守卫(即占据或者攻击)所有带标记的格子。

分析:因为不知道放几个皇后可以守卫所有带标记的格子,即回溯法求解时解答树的深度没有明显的上限,所以使用迭代加深搜索。

将棋盘的每个格子标记为0~n*m-1,依次枚举守卫的皇后个数,枚举当前守卫的皇后个数下所有的放置情况,看是否能全部守卫。(枚举方式i:1~n,j:i+1~n……)

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , -, , -, -, , };
const int dc[] = {-, , , , -, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = + ;
const int MAXT = + ;
using namespace std;
char a[][];
int vis[][];
int mark[][];
int kase;
int n, m;
bool judge(){
for(int i = ; i < n; ++i){//判断所有被标记的正方形是否被保护
for(int j = ; j < m; ++j){
if(mark[i][j] && !vis[][i] && !vis[][j] && !vis[][j + i] && !vis[][j - i + n])
return false;
}
}
return true;
}
bool dfs(int cur, int pos, int tot){
if(cur == tot){//放置tot个皇后是否可全保护
if(judge()){
printf("Case %d: %d\n", kase, tot);
return true;
}
return false;
}
else{
for(int i = pos; i < n * m; ++i){//所有点被标记成0~n*m-1
int x = i / m;//当前位置的横坐标
int y = i % m;
int tmp1 = vis[][x];
int tmp2 = vis[][y];
int tmp3 = vis[][x + y];
int tmp4 = vis[][y - x + n];
vis[][x] = vis[][y] = vis[][x + y] = vis[][y - x + n] = ;
if(dfs(cur + , i + , tot)) return true;//此处优化,i + 1下次枚举是当前位置再加1,避免情况重复
vis[][x] = tmp1;
vis[][y] = tmp2;
vis[][x + y] = tmp3;
vis[][y - x + n] = tmp4;
}
}
return false;//枚举当前所有情况不满足
}
int main(){
while(scanf("%d", &n) == ){
if(!n) return ;
++kase;
scanf("%d", &m);
memset(a, , sizeof a);
memset(mark, , sizeof mark);
for(int i = ; i < n; ++i){
scanf("%s", a[i]);
}
for(int i = ; i < n; ++i){
for(int j = ; j < m; ++j){
if(a[i][j] == 'X'){
mark[i][j] = ;
}
}
}
for(int i = ; ; ++i){
memset(vis, , sizeof vis);
if(dfs(, , i)) break;
}
}
return ;
}

UVA - 11214 Guarding the Chessboard(守卫棋盘)(迭代加深搜索)的更多相关文章

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

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

  2. UVA - 11214 Guarding the Chessboard(迭代加深搜索)

    题目: 输入一个n*m的棋盘(n,m<10),某些格子有标记,用最少的皇后守卫(即占据或攻击)所有的标记的格子.输出皇后的个数. 思路: 一开始没有想到用迭代加深搜索,直接dfs结果还没写完就发 ...

  3. UVA 11214 Guarding the Chessboard

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

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

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

  5. UVA-11214 Guarding the Chessboard (迭代加深搜索)

    题目大意:在一个国际象棋盘上放置皇后,使得目标全部被占领,求最少的皇后个数. 题目分析:迭代加深搜索,否则超时. 小技巧:用vis[0][r].vis[1][c].vis[2][r+c].vis[c- ...

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

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

  7. UVA 10160 Servicing Stations(状态压缩+迭代加深)

    [题目链接] LInk [题目大意] 给出一些点和边,选择一个点就能把这个点和相邻的点都覆盖,求最小点覆盖 [题解] 我们压缩点被覆盖的状态,迭代加深搜索覆盖的最小点数, 当剩余的点全部选上时都无法完 ...

  8. Power Calculus UVA - 1374 迭代加深搜索

    迭代加深搜索经典题目,好久不做迭代加深搜索题目,拿来复习了,我们直接对当前深度进行搜索,注意剪枝,还有数组要适当开大,因为2^maxd可能很大 题目:题目链接 AC代码: #include <i ...

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

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

随机推荐

  1. scrapy 实现mysql 数据保存

    开始用scrapy 爬取数据的时候  开始用同步操作始终会报1064  的错误  因为 mysql 语法和导入的字段不兼容 尝试了  n  次之后  开始用  异步爬取  虽然一路报错 但是还是能把数 ...

  2. stm32_f103使用gcc编译的环境下printf打印函数的实现

    前记   gcc编译使用的printf打印函数需要的底层函数是和其他编译器不同的,以前的是无法使用的,这里有两种方法,一种是使用gcc库里面的printf函数,自己实现底层IO函数_write.另外一 ...

  3. Day9 - G - Doing Homework HDU - 1074

    有n个任务,每个任务有一个截止时间,超过截止时间一天,要扣一个分.求如何安排任务,使得扣的分数最少.Input有多组测试数据.第一行一个整数表示测试数据的组数第一行一个整数n(1<=n<= ...

  4. java程序题目解析

    (选择一项) A: 不能有括号 B: C: 确定最后一位 D: 正确答案是 B  本题考查的是Java数组概念,数组下标是从零开始的,但是数据下标的总量和数据长度相同 (选择一项) A: B: 顺序不 ...

  5. 12541:TNS无监听状态

    上次在项目上遇见数据库报这个问题,然后网上几乎都是让重新进行配置数据库.配置多次之后还是无效,最后找到了问题的根源. 使用的是Oracle数据库,用PLSQL登录报的这个错误. 在计算机全局搜索:li ...

  6. HDU1880 魔咒词典

    题目大意:对应的输入多行,每行两个字符串,两个字符串互相映射.接下来询问的时候,如果这个字符串出现过,输出其对应的字符串. 分析:二重哈希来判断字符串是否存在,输出其对应的字符串就行.二重哈希的入门题 ...

  7. JS动态判断设备类型为PC或者移动端,然后根据设备加载相应的代码

    这里是通过JS判断设备之后加载相应的网站,如果是移动端加载m开头的网站域名,如果是PC端就加载 www.开头的正式域名 <script> (function () { var url = ...

  8. python 输入年月日,返回当天是星期几

    引入内置模块calendar,输入年.月.日,根据weekday(year,month,day)的返回值,输出该日期是星期几.函数weekday()返回0-6分别对应星期一至星期日 import ca ...

  9. java字符,字符串,数字之间的转换

    string 和int之间的转换 string转换成int  :Integer.valueOf("12") int转换成string : String.valueOf(12) ch ...

  10. python假设一段楼梯共 n(n>1)个台阶,小朋友一步最多能上 3 个台阶,那么小朋友上这段楼 梯一共有多少种方法

    我们先把前四节种数算出来(自己想是哪几类,如果你不会算,那就放弃写代码吧,干一些在街上卖肉夹馍的小生意,也挣得不少) 标号 1    2    3     4 种类 1    2    4     7 ...