n皇后问题(位运算优化)

12 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值