您的位置:首页 > 其它

ZCMU 1803 2n皇后问题 (DFS)

2017-07-04 13:59 190 查看

Problem D: 2n皇后问题

Time Limit: 1 Sec  Memory Limit:
128 MB
Submit: 25  Solved: 19

[Submit][Status][Web
Board]

Description

给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

Input

 输入的第一行为一个整数n,表示棋盘的大小。接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

Output

 输出一个整数,表示总共有多少种放法。

Sample Input

4 1 1 1 11 1 1 11 1 1 1 1 1 1 14 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Sample Output

20

解题思路:方法应该很多,我的办法是按照传统的N皇后问题来做,每行先放白皇后,再放同行的黑皇后,再放下一行的白皇后......直到放n+1行白皇后的时候就得到一个解。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

int mp[10][10];

int rW[20],rB[20];//i-j+n左斜线
int mW[20],mB[20];//i+j右斜线
int lW[10],lB[10];//j竖行
int ans;

void DFSw(int k,int n)//放白皇后
{
void DFSb(int k,int n);

if(k>n)
{
ans++;
return;
}

int i=k;
for(int j=1;j<=n;j++)
{
if(mp[i][j]&&rW[i-j+n]==0&&mW[i+j]==0&&lW[j]==0)
{
mp[i][j]=0;
rW[i-j+n]=1;
mW[i+j]=1;
lW[j]=1;
DFSb(k,n);//放完白皇后立马放同行的黑皇后
//cout<<"w "<<k<<' '<<j<<endl;
mp[i][j]=1;
rW[i-j+n]=0;
mW[i+j]=0;
lW[j]=0;
}
}
}

void DFSb(int k,int n)
{
int i=k;
for(int j=1;j<=n;j++)
{
if(mp[i][j]&&rB[i-j+n]==0&&mB[i+j]==0&&lB[j]==0)
{
mp[i][j]=0;
rB[i-j+n]=1;
mB[i+j]=1;
lB[j]=1;
DFSw(k+1,n);//放完黑皇后立马放下一行的白皇后
//cout<<"b "<<k<<' '<<j<<endl;
mp[i][j]=1;
rB[i-j+n]=0;
mB[i+j]=0;
lB[j]=0;
}
}
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&mp[i][j]);
}
}
memset(rW,0,sizeof(rW));
memset(rB,0,sizeof(rB));
memset(mW,0,sizeof(mW));
memset(mB,0,sizeof(mB));
memset(lW,0,sizeof(lW));
memset(lB,0,sizeof(lB));

DFSw(1,n);
printf("%d\n",ans);
}
return 0;
}

/**************************************************************
Problem: 1803
User: HUCM201702
Language: C++
Result: Accepted
Time:80 ms
Memory:1480 kb
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DFS ACM 算法