ZCMU 1803 2n皇后问题 (DFS)

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
****************************************************************/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值