蓝桥杯之 2n皇后问题(双层dfs,暴力)

Description

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

Input

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

如果一个整数为0,表示对应的位置不可以放皇后。

Output

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

Sample Input

No.1
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

No.2
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1

Sample Output

No.1
2

No.2
0

Source

蓝桥杯
链接:
 
分析:有黑皇后和白皇后,规则跟N皇后问题是一样的,先放一种皇后,比如先放白皇后,会产生x中放置的方案,然后再在这x个方案中放置黑皇后,一个位置只能放一个棋子,不同种类的皇后可以放置在同行,同列,或者同斜列上
直接双层dfs暴力即可
code:
#include<bits/stdc++.h>
using namespace std;
#define max_v 10
#define me(a,x) memset(a,x,sizeof(a))
int a[max_v][max_v];
int M[max_v],L[max_v],R[max_v];
int c;
int n;
struct node
{
    int b[max_v][max_v];
}p[max_v*max_v];
void f(int k)
{
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            p[k].b[i][j]=a[i][j];
        }
    }
}
void dfs1(int i)
{
        for(int j=0;j<n;j++)
        {
            if(a[i][j]==0)
                continue;
            if(M[j]==0&&L[i+j]==0&&R[i-j+n]==0&&a[i][j]==1)
            {
                M[j]=L[i+j]=R[i-j+n]=1;
                a[i][j]=-1;
                if(i==n-1)
                {
                    c++;
                    f(c);
                }else
                {
                    dfs1(i+1);
                }
                M[j]=L[i+j]=R[i-j+n]=0;
                a[i][j]=1;
            }
        }
}
void dfs2(int i,int k)
{
    for(int j=0;j<n;j++)
        {
            if(p[k].b[i][j]==0||p[k].b[i][j]==-1)
                continue;
            if(M[j]==0&&L[i+j]==0&&R[i-j+n]==0&&p[k].b[i][j]==1)
            {
                M[j]=L[i+j]=R[i-j+n]=1;
                p[k].b[i][j]=-1;
                if(i==n-1)
                {
                    c++;
                }else
                {
                    dfs2(i+1,k);
                }
                M[j]=L[i+j]=R[i-j+n]=0;
                p[k].b[i][j]=1;
            }
        }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        cin>>a[i][j];
    me(M,0);
    me(L,0);
    me(R,0);
    c=0;
    dfs1(0);

    int rs=0;
    int m=c;
    for(int i=1;i<=m;i++)
    {
        me(M,0);
        me(L,0);
        me(R,0);
        c=0;
        dfs2(0,i);
        rs+=c;
    }
    cout<<rs<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/yinbiao/p/10467443.html