zoukankan      html  css  js  c++  java
  • n皇后问题(位运算优化)

    n皇后问题

    题目描述:
    众所不知, rly现在不会玩国际象棋。但是,作为一个OIer, rly当然做过八
    皇后问题。这里再啰嗦几句,皇后可以攻击到同行同列同对角线,在n*n的方格中摆n个皇后使其互不攻击到,求不同的解的数量,这就是经典的n皇后问题。
    现在问题推广到n皇后问题,这个问题对于你而言实在是小菜一叠。但因为上一次rly把棋盘弄破了,又拿不出新的,所以rly打算难一点点,问题就是破棋盘上的n皇后问题。他想知道……(你们懂的)。
    棋子都是相同的。
    输入说明:
    一行,一个正整数N。
    接下来N行,每行N个数,要么为0,表示没坏,要么1,表示坏了。
    输出说明:
    一行,输出不同的解的数量。
    样例输入:
    4
    1 0 1 1
    1 1 1 0
    0 1 1 1
    1 1 0 1
    样例输出:
    1
    数据范围:
    对于40%的数据, N<=13。
    对于100%的数据, N<=16。
    其中有30%的数据,棋盘没有破(你可以认为rly又去买了一个新的)。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn=30;
    int n,ans,a[maxn];
    void dfs(int t,int l,int x,int y)//当前行t的状态,x用二进制表示一条对角线,y用二进制表示另一条对角线的状态 
    {
        if(t==n+1)
        {
            ans++;
            return;
        }
        int s=((1<<n)-1)&(~(a[t]|l|x|y));
        /*
        S存的能放的位置 先把行 列 对角线或起来现在1表示已经放过 
        然后取反后1代表没放过能放得到能放的 
        */
        while(s)
        {
            int z=s&(-s);//lowbit找能放的位置-->即找1 
            dfs(t+1,l+z,(z+x)<<1,(y+z)>>1);//l,x,y能更新放的位置(对角线到下一行会移一列)
            s-=z;
        }
    }
    int main()
    {
        freopen("queen.in","r",stdin);
        freopen("queen.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                int x;
                scanf("%d",&x);
                if(x) a[i]+=(1<<j-1);
            }
        }
        dfs(1,0,0,0);
        cout<<ans;
        fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    武汉大学2020年数学分析考研试题
    南开大学2020年数学分析考研试题
    南开大学2020年高等代数考研试题
    华中科技大学2020年数学分析考研试题
    华南理工大学2020年数学分析考研试题
    华东师范大学2020年数学分析考研试题
    华东师范大学2020年高等代数考研试题
    哈尔滨工业大学2020年数学分析考研试题
    大连理工大学2020年高等代数考研试题
    大连理工大学2020年数学分析考研试题
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070890.html
Copyright © 2011-2022 走看看