八皇后问题

 

八皇后问题一般情况下朴素的深搜就可以了,但可以对其进行二进制优化(这大概是目前最优的深搜算法):

 

用二进制表示状态.1表示该点不能放(与其他位置的皇后排斥或初始状态就不能放).0表示该点可以放皇后;

dfs保存四个参数:之前所有行的状态,从左上到右下对角线的状态,从右上到左下对角线的状态,当前为第几行;

获取当前哪一位可以放置皇后:将四者进行或运算,得到的状态中为0的就可以放置皇后。为了方便,将其取反,1的位置表示可以放一个皇后;

利用好lowbit()运算就可以快速得到最后一位1的位置。将状态中的1减掉,继续找下一个1;

 

知道当前行的状态全为1时,即每一行都有一个皇后时,ans++;

#include <bits/stdc++.h>
using namespace std;
int a[10010];
char tmp[10010];
int tot;
long long ans;
inline int lowbit(int x)
{
    return x&(-x);
}
void dfs(int now,int b,int c,int dep)
{
    if(now==tot){
        ++ans;
        return;
    }
    int sum=tot&(~(now|b|c|a[dep]));
    while(sum){
        int p=lowbit(sum);
        sum-=p;
        dfs(now+p,(b+p)*2,(c+p)/2,dep+1);
    }
}
int main()
{
    int n;
    cin>>n;
    tot=(1<<n)-1;
    for(register int i=1;i<=n;i++){
        scanf("%s",tmp+1);
        for(int j=1;j<=n;j++){
            if(tmp[j]=='.') a[i]=a[i]|(1<<(n-j));
        }
    }
    dfs(0,0,0,1);
    cout<<ans;
} 

 

posted @ 2019-09-10 19:20  神之右大臣  阅读(340)  评论(0编辑  收藏  举报