您的位置:首页 > 其它

11214 - Guarding the Chessboard

2015-07-19 19:52 295 查看
Problem G

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

Output for the Sample Input

Case 1: 5

Case 2: 1

我有话说:

根据八皇后问题的枚举。我们也可以依样画葫芦进行枚举。枚举对象是一个个格子。也要记录每行每列每条斜线上的是否有皇后。然后为了统计最小的个数,迭代加深搜索再好不过。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=100+10;
int kase=0,n,m;
int vis[4][maxn],target[15][15];
void Init()
{
memset(target,0,sizeof(target));

char ch;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
do{scanf("%c",&ch);}while(!isprint(ch));
if(ch=='X')target[i][j]=1;
}
}
bool arrive()
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(target[i][j]&&!vis[0][i]&&!vis[1][j]&&!vis[2][i+j]&&!vis[3][n+j-i])
return false;
}
return true;
}
int dfs(int cur,int d,int maxd)
{
if(d==maxd){
if(arrive()){
printf("Case %d: %d\n",++kase,d);
return 1;
}
return 0;
}

for(int pos=cur;pos<n*m;pos++)
{
int r=pos/m,l=pos%m;
int tmp1=vis[0][r],tmp2=vis[1][l],tmp3=vis[2][r+l],tmp4=vis[3][n+l-r];
vis[0][r]=vis[1][l]=vis[2][r+l]=vis[3][n+l-r]=1;
if(dfs(pos,d+1,maxd))return 1;
vis[0][r]=tmp1,vis[1][l]=tmp2,vis[2][r+l]=tmp3,vis[3][n+l-r]=tmp4;
}
return 0;
}
int main()
{
while(scanf("%d%d",&n,&m)==2&&n&&m){

Init();
for(int maxd=0;;maxd++)
{
memset(vis,0,sizeof(vis));
if(dfs(0,0,maxd))break;
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: