您的位置:首页 > 其它

UVA 11214 Guarding the Chessboard (迭代)

2016-05-29 22:43 381 查看
题意:给一个n*m的棋盘,由‘X’和‘.’组成,要求往棋盘上摆国际象棋的皇后,最终使得所有的‘X’标记的位置能够被皇后以及皇后的攻击范围所覆盖(皇后的攻击范围是当前所在点的行,列以及对角线),此时输出所需要的皇后的最小个数

这里用了一个vis[a][b]数组来记录当前点是否放了皇后,a分别代表当前点的行,列,对角线1,对角线2,这个思想感觉是很值得学习的

思路肯定是用深度优先搜索,但要注意是逐个位置搜索,所以用二重循环遍历整个矩阵是不容易的,之前做的八皇后用的回溯法在这里思路是一样的。

通过这道题了解了迭代深搜的思想,确实是个很好的思维

代码如下:

#include<cstring>
#include<iostream>
using namespace std;
int n,m;
int a[15][15];
int vis[4][30];
int dmax;
bool pan()
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
if(a[i][j]&&!vis[0][i]&&!vis[1][j]&&!vis[2][i+j]&&!vis[3][i-j+10]) return false;
return true;
}
bool dfs(int cpos,int d)
{
if(d==dmax)
{
if(pan()) return true;
}
else
{
for(int pos=cpos; pos<=n*m; pos++)
{
int i,j;
if(pos%m==0) j=m;
else j=pos%m;
i=(pos-1)/m+1;
int ca=vis[0][i],cb=vis[1][j],cc=vis[2][i+j],cd=vis[3][i-j+10];
vis[0][i]=vis[1][j]=vis[2][i+j]=vis[3][i-j+10]=1;
if(dfs(pos,d+1)) return true;
vis[0][i]=ca,vis[1][j]=cb,vis[2][i+j]=cc,vis[3][i-j+10]=cd;
}
}
return false;
}
int main()
{
int cases=1;
while(cin>>n&&n)
{
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
cin>>m;
char ch;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
cin>>ch;
if(ch=='X') a[i][j]=1;
else if(ch=='.') a[i][j]=0;
}
for(dmax=0;; dmax++)
if(dfs(1,0)) break;
cout<<"Case "<<cases++<<": "<<dmax<<"\n";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UVA 暴力