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;
}