zoukankan      html  css  js  c++  java
  • 蓝桥杯之 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;
    }
  • 相关阅读:
    CentOS安装thrift
    6个用于大数据分析的最好工具
    我的助理辞职了!——给不听话的下属看看
    用Redis bitmap统计活跃用户、留存
    Java从入门到精通——数据库篇Oracle 11g服务详解
    Java从入门到精通——数据库篇之OJDBC版本区别
    非常有用!eclipse与myeclipse恢复已删除的文件和代码
    Redis 代理服务Twemproxy
    Redis集群明细文档
    正则表达式
  • 原文地址:https://www.cnblogs.com/yinbiao/p/10467443.html
Copyright © 2011-2022 走看看