UVa11214 Guarding the Chessboard (IDA*)

链接:http://vjudge.net/problem/23958

分析:控制最大递归深度为maxd,也就是枚举个数maxd个皇后守卫的时候,dfs以行枚举放皇后守卫的位置,确保放皇后守卫的位置的行,列,主和副对角线上没有其它守卫,否则就不是最优的了,每次递归从上次放的行的下一行开始放,放满maxd个后进行判断是否所有标记格子都被攻击到。是则直接返回true输出最少守卫,否则返回递归上一层继续枚举,vis要复位。

 1 #include <cstdio>
 2 #include <cstring>
 3
 4 const int maxn = 11;
 5
 6 int n, m, maxd;
 7 char G[maxn][maxn];
 8 bool vis[4][maxn << 1];
 9
10 bool dfs(int cur, int d) {
11     if (d == maxd) {
12         for (int i = 1; i <= n; i++)
13             for (int j = 1; j <= m; j++)
14                 if (G[i][j] == ‘X‘ && !vis[0][i] && !vis[1][j] && !vis[2][j - i + n] && !vis[3][i + j])
15                     return false;
16         return true;
17     }
18     for (int i = cur; i <= n; i++)
19         for (int j = 1; j <= m; j++) {
20             if (!vis[0][i] || !vis[1][j] || !vis[2][j - i + n] || !vis[3][i + j]) {
21                 bool br = vis[0][i], bc = vis[1][j], bm = vis[2][j - i + n], bd = vis[3][i + j];
22                 vis[0][i] = vis[1][j] = vis[2][j - i + n] = vis[3][i + j] = true;
23                 if (dfs(cur + 1, d + 1)) return true;
24                 vis[0][i] = br, vis[1][j] = bc, vis[2][j - i + n] = bm, vis[3][i + j] = bd;
25             }
26         }
27     return false;
28 }
29
30 int main() {
31     int kase = 0;
32     while (scanf("%d%d", &n, &m) == 2 && n) {
33         for (int i = 1; i <= n; i++) scanf("%s", G[i] + 1);
34         for (maxd = 0; ; maxd++) {
35             memset(vis, 0, sizeof(vis));
36             if (dfs(1, 0)) break;
37         }
38         printf("Case %d: %d\n", ++kase, maxd);
39     }
40     return 0;
41 }
时间: 2024-10-08 03:37:11

UVa11214 Guarding the Chessboard (IDA*)的相关文章

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

题目大意:在一个国际象棋盘上放置皇后,使得目标全部被占领,求最少的皇后个数. 题目分析:迭代加深搜索,否则超时. 小技巧:用vis[0][r].vis[1][c].vis[2][r+c].vis[c-r+N]分别标志(r,c)位置相对应的行.列.主.副对角线有没有被占领(详见<入门经典(第2版)>P193),其中N表示任意一个比行数和列数都大(大于等于)的数. 代码如下: # include<iostream> # include<cstdio> # include&l

UVa11214 - Guarding the Chessboard

给出m*n棋盘上的目标点,求最少用几个皇后可以守卫所有目标点. 类似八皇后做法,2维数组标记行.列.主对角线.副对角线. 有个加速的技巧,测试之后发现10*10的棋盘全部守卫至少需要5个,所以上限就是5,当maxd等于5时直接输出,不进行搜索. #include<cstdio> #include<cstring> using namespace std; const int maxn=11; int n,m,t,maxd; bool g[maxn][maxn],vis[4][max

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

题目链接 正解是IDA*+四个方向判重,但由于是个裸的可重复覆盖问题,可以用DLX水过~ 每个格子与放上皇后能干掉的标记连边,跑可重复覆盖DLX.注意要用IDA*来优化,否则会超时. 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=10+2; 5 int n,m,np,ka; 6 char s[N][N]; 7 struct P {int x,y;} p[N*N]; 8

Guarding the Chessboard(UVa 11214)

本题题意: 输入一个n*m的棋盘,某些格子有标记,用最少的皇后占据或者攻击所以带标记的格子.皇后的攻击范围为同行同列和同对角线. 可以使用IDA*算法,即从样例可以发现只需要最多5个棋子就可以对棋盘上所有地方进行攻击,因而使用IDA*进行对应的剪枝即可. #include<cstdio> #include<cstring> using namespace std; int n,m,kase=0,maxd; bool vis[4][30];///表示皇后已经攻击的范围,vis[0][

Guarding the Chessboard

Given an n ∗ m chessboard with some marked squares, your task isto place as few queens as possible to guard (attack or occupy) allmarked squares. Below is a solution to an 8 ∗ 8 board with everysquare marked. Note that queens can be placed on non-mar

11214 - Guarding the Chessboard(暴力搜索)

IDA*算法, 从小到大枚举深度上限,不过该题是有深度上限的,题目中的第一个样例表明:最多需要5个皇后就可以覆盖整个棋盘 . 利用紫书上的技巧,我们可以快速的判断任意两个棋子是不是在同一行.同一列.同一对角线 (详情见紫书P193那两个图). 这样之后暴力搜索就可以了 . 每一层需要O(nm)的复杂度,但是实际上并不需要那么大的复杂度 .和八皇后问题类似 , 当前行之前的行已经放置了皇后,所以不必在管,每次从下一行开始放置就好 . 细节见代码: #include<bits/stdc++.h>

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

就是个暴力,和八皇后很像,但是还是要加一些的剪枝的. 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<<

POJ——T2446 Chessboard

http://poj.org/problem?id=2446 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18560   Accepted: 5857 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of c

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu