计蒜客——2n皇后问题

题目描述:
给定一个 n∗n 的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角 线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法? n 小于等于 8
输入格式
输入的第一行为一个整数 n ,表示棋盘的大小。
接下来 n 行,每行 n 0 1 的整数,如果一个整数为 1, 表示对应的位置可以放皇后,如果一个整数为 0 ,表示对应的位置不可以放皇后。
输出格式
输出一个整数,表示总共有多少种放法。
样例输入1
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出1
2
样例输入2
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出2
0

题目分析:八皇后问题的变种,同样可以采用深度优先搜索的方法进行处理。

#include <iostream>
using namespace std;
int n,s[9][9],num=0,ans;
bool vis[100][2];
bool hang[100][2];
bool zheng[100][2];
bool fan[100][2];
void dfs(int idx)
{
    if(idx>=n){//结束条件
        ans++;// 之前的搜索过程已经保证合法
        return;
    }
    for(int i=0;i<n;i++){
    if(!hang[i][0]&&!zheng[idx+i][0]&&!fan[idx-i+n-1][0]&&s[idx][i]==1){
            hang[i][0]=true;
            zheng[idx+i][0]=true;
            fan[idx-i+n-1][0]=true;
            for(int j=0;j<n;j++){
    if(i!=j&&!hang[j][1]&&!zheng[idx+j][1]&&!fan[idx-j+n-1][1]&&s[idx][j]==1){
            // i!=j:不能放在用一个位置
                    hang[j][1]=true;
                    zheng[idx+j][1]=true;
                    fan[idx-j+n-1][1]=true;
                    dfs(idx+1);
                    hang[j][1]=false;
                    zheng[idx+j][1]=false;
                    fan[idx-j+n-1][1]=false;
                }
            }
            hang[i][0]=false;
            zheng[idx+i][0]=false;
            fan[idx-i+n-1][0]=false;
        }
    }
}
int main()
{
    cin>>n;
    ans=0;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>s[i][j];
        }
    }
    dfs(0);
    cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/samsungwhite_ssw/article/details/80556621
今日推荐