Given an n ∗ m chessboard with some marked squares, your task is
to place as few queens as possible to guard (attack or occupy) all
marked squares. Below is a solution to an 8 ∗ 8 board with every
square marked. Note that queens can be placed on non-marked
squares.
Input
The input consists of at most 15 test cases. Each case begins with
a line containing two integers n, m (1 < n, m < 10) the size of
the chessboard. Next n lines each contain m characters, ‘X’ denotes
marked square, ‘.’ denotes unmarked squares. The last case is
followed by a single zero, which should not be processed.
Output
For each test case, print the case number and the minimal number of queens needed.
Sample Input
8 8
XXXXXXXX
XXXXXXXX
XXXXXXXX
XXXXXXXX
XXXXXXXX
XXXXXXXX
XXXXXXXX
XXXXXXXX
8 8
X…
.X…
…X…
…X…
…X…
…X…
…X.
…X
0
Sample Output
Case 1: 5
Case 2: 1
【题目大意:】
给定一个棋盘,每个’X’的位置都需要被占住或者保卫住,国际象棋皇后保卫的地方是自己所在这一行、这一列、以及两条对角线
【题目分析:】
- vis[0][i]标记i行被保护。
- vis[1][j]标记j列被保护。
- vis[2][i+j]标记(i,j)右斜对角线方向被标记。
- vis[3][Maxn+i-j]标记左斜对角线方向被标记(Maxn保证不会出现负数)。
- 最好是自己画个棋盘看一下,
- 主要思路还是迭代加深搜索,每次枚举最大的皇后个数,然后判断用ret个皇后能否占住或者保卫所有的’X’型区域
这是从学长给的刷题列表里找的一道题,看不懂英文题面,没想到又是一个迭代加深搜索,还好这个迭代加深搜索比较简单,算是个入门级的迭代加深搜索吧
【收获:】
数组表示棋盘状态,尤其是对角线
//
// Created by DELL on 2020/2/18.
//
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define Maxn 11
using namespace std;
int n,m;
char maps[Maxn][Maxn];
bool vis[4][2 * Maxn];
inline bool Judge() {
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(maps[i][j] == 'X' && !vis[0][i] && !vis[1][j] && !vis[2][i + j] && !vis[3][i - j + Maxn]) return false;
return true;
}
bool DFS(int cur,int Maxd) {
if(Maxd == 0) {
if(Judge()) return true;
else return false;
}
for(int i=cur; i<=n; i++) {
for(int j=1; j<=m; j++) {
bool a = vis[0][i] ,b = vis[1][j] ,c = vis[2][i + j],d = vis[3][i - j + Maxn];
vis[0][i] = vis[1][j] = vis[2][i + j] = vis[3][i - j + Maxn] = 1;
if( DFS(i + 1,Maxd - 1)) return true;
vis[0][i] = a,vis[1][j] = b,vis[2][i + j] = c,vis[3][i - j + Maxn] = d;
}
}
return false;
}
int Solce() {
int ret = 0;
for(ret = 1; ; ret ++){
memset(vis,0,sizeof(vis));
if(DFS(1,ret)) break;
}
return ret;
}
int main(int argc,char* argv[]) {
int kase = 0;
while(scanf("%d",&n) == 1 && n) {
scanf("%d",&m);
memset(maps,0,sizeof(maps));
for(int i=1; i<=n; i++) scanf("%s",maps[i] + 1);
int Ans = Solce();
printf("Case %d: %d\n",++kase,Ans);
}
return 0;
}