[位运算]【洛谷P1562】 还是N皇后 详解

本文通过使用递归和位操作的方法解决了一个变形的八皇后问题。该问题要求在一个n×n的棋盘上放置n个皇后,使得任意两个皇后都不在同一行、列或对角线上,并且棋盘上有一些固定不能放置皇后的格子。文章详细介绍了如何通过C++代码实现这一过程。
码字格式总有问题,,,换图了
     

【实现代码】

#include <iostream>  
#include<stdio.h>  
using namespace std;  
int n,ans,End,map[20];  
void dfs(int row,int ld,int rd,int d) {   
    if(d>n) { 
        ans++;return;  
    }  
    int pos=End&(~(row|ld|rd|map[d])),p;  //可以分三步来理解:1、先|方向找到最终的位置 2、取反(~) 3、用End &上,去掉多余的1。至于End是什么,其实就是(1>>n)-1即n位的1,n位前的0回被抹掉,表示可放置的1(0取反)不受影响
        while(pos) {  
        p=pos&(-pos);//用lowbit原理 
        pos-=p;  //把用过的可能性减掉

        dfs(row+p,(ld+p)<<1,(rd+p)>>1,d+1); //状态转移方程,下一行的状态
     }  
}  
int main() {  
    char s[20];    
    scanf("%d\n",&n); //这是个坑点!!!cin会读进换行符
    End=(1<<n)-1; //上文有解释
for(int i=1; i<=n; i++) {  
        gets(s);  
        for(int j=1; j<=n; j++)  
            map[i]=(s[j-1]=='.')+(map[i]<<1);//这个东西其实就是手动造出表示起始状态的二进制数,就是遇到" . " 就放1表示不能放,如果没到第n列,就不停的往后补零}  
    dfs(0,0,0,1); 
    printf("%d",ans);  
    return 0;  

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值