第九十五題 UVa11214 Guarding the Chessboard

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;
}
發佈了776 篇原創文章 · 獲贊 36 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章