• n皇后问题,状态压缩


    N皇后问题

    Description

    八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后。为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。

    Input

    一个数n,表示棋盘大小为n*n,有n个皇后。

    Output

    只有一个数字,为解的个数。当没有解时输出0。

    Sample Input

    8

    Sample Output

    92

    AC 通道:  http://oj.changjun.com.cn/problem/detail/pid/1099

    这是一个经典的状态压缩题,用到了大量的位运算;

    首先看到这题,我们的第一想法是,仍像8皇后问题那样开列数组与对角线的数组,采用搜索回溯法,但我们知道

    搜索时,数组里面存的无非就是存当前位置有没有皇后,使用一个LL去存储当前的状态,然后通过存的状态去搜索即可,状态的修改通过位移以及位运算符进行修改即可,大大节约空间和时间(这也是节约能源啊)!

    具体来说,初始化一个棋盘,默认为空,即全为0,连续的64个0,

    假设棋盘放了皇后,放置成这样:

    用二进制表示为1(90)1(530)

    如果要在某个位置放一个皇后,表达式为p=p|(1<<xx)

    例如,在(7,6)处放置一个皇后,xx为8*(8-7)+(8-6),也就是将一个二维坐标转为1维然后存入一个数组中


    下面看下代码实现大笑。。。

    //  I'm YinPengzhe    Congratulations!
     1 #include<cstdio>
     2 //#include<iostream>
     3 int N,Ans;
     4 void dfs(int Col,int Maindig,int assdig)// Col 列的情况  Maindig 主对角线  assdig 副对角线
     5 {
     6     if(Col==(1<<N)-1) {
     7         Ans++;
     8         return;
     9     }
    10     int empty_col=((1<<N)-1) & (~ (Col|Maindig|assdig));
    11     while(empty_col) {
    12         int cal=empty_col & ((~ empty_col)+1);
    13         empty_col &= ~cal;
    14         dfs(Col|cal,(Maindig|cal) >> 1,(assdig|cal) << 1);
    15     }
    16     return;
    17 }
    18 int main() {
    19     scanf("%d",&N);
    20     Ans=0;
    21     dfs(0,0,0);
    22     printf("%d",Ans);
    23     return 0;
    24 }
    View Code


    中间一些位运算的操作具体时间这样的;

    Col是表示列的拜访情况,如果到了终点状态,则左右的列上都会摆一个1,那么对应的2进制数为(1<<N)-1;

    所以Col & ((1<<N)-1) 即为目标状态

    empty_col 为当前状态下所有能拜1 的情况,即算出来后每一位能摆1 的都为 1 ,(Col|Maindig|assdig)为所有情况,~则把摆了的变为0,能摆的变为1;所以与全部都为1的((1<<N)-1) & 则为当前值;

    cal=empty_col & ((~ empty_col)+1);这是取最末尾的1的值

    我们想,e & (~e)肯定为0;

    假设e 的从末尾数第一个为1的位值为First

    则First后的全为0;当取反后,First变为了0,前面全为1,+1后一直进位到First,Firtst成为了1,她后面的全变为了0;

    First前应为反了一次,所以 & e 肯定是0,First 后的也一定为0,所以得到的即是第一个1的值;//十分巧妙吧吐舌头

    empty_col &= ~cal;  删去她;
    此处推荐一个讲的很好的博客:  http://blog.csdn.net/txl199106/article/details/55505785
    YEAH




    我想要的 我自然会认真.
  • 相关阅读:
    Java Lambda表达式初探
    什么时候使用CountDownLatch
    Spring官网改版后下载
    JAVA多线程实现的四种方式
    Java四种线程池的使用
    CentOS配置本地yum源(使用镜像iso文件)
    深入浅出解析大数据平台架构
    How Kafka’s Storage Internals Work
    Understanding Kafka Consumer Groups and Consumer Lag
    Understanding, Operating and Monitoring Apache Kafka
  • 原文地址:https://www.cnblogs.com/ypz999/p/6573490.html
Copyright © 2020-2023  润新知