第九十五题 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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章