zoukankan      html  css  js  c++  java
  • 八皇后-位运算

    记录一下--一个名叫vj的地方把我的回溯代码一直wa,,,

    逼我现学位运算~~~~

    #include <iostream>
    #include <string>
    #include <string.h>
    using namespace std;
    
    long sum = 0, upperlim = 1;
    void test(long row, long ld, long rd)
    /*
     * 分别表示在纵列和两个对角线方向的限制条件下这一行的哪些地方不能放
     * 注意:是不能放!!!
     */
    {
        if (row != upperlim)
        {
    
            long pos = upperlim & ~(row | ld | rd);
            //位于该行上的冲突位置就用row、ld和rd中的1来表示。
            // 把它们三个并起来,得到该行所有的禁位,取反后就得到所有可以放的位置(用pos来表示)。
            while (pos)//从所有非禁位寻找
            {
                long p = pos & -pos;
                pos -= p;
                /*
                 * 其结果是取出最右边的那个1。这样,p就表示该行的某个可以放子的位置,
                 * 把它从pos中移除并递归调用test过程。
                 */
                test(row + p, (ld + p) << 1, (rd + p) >> 1);
                // row + p,将当前列置1,表示记录这次皇后放置的列。
                // (ld + p) << 1,标记当前皇后左边相邻的列不允许下一个皇后放置。
                // (ld + p) >> 1,标记当前皇后右边相邻的列不允许下一个皇后放置。
                // 此处的移位操作实际上是记录对角线上的限制,只是因为问题都化到一行网格上来解决,所以表示为列的限制就可以了。显然,随着移位
                // 在每次选择列之前进行,原来N×N网格中某个已放置的皇后针对其对角线
                // 上产生的限制都被记录下来了
            }
        }
        else
        {
            sum++;
        }
    }
    
    int main() {
    
        int n;
        while(cin>>n && n!=0) {
            upperlim = (upperlim << n) - 1;
            test(0, 0, 0);
            printf("%d
    ", sum);
            upperlim=1;
            sum=0;
    
        }
        return 0;
    }

    还是觉得位运算懵呜呜呜

  • 相关阅读:
    (转)expfilt 命令
    (转)第二十三节 inotify事件监控工具
    数据结构之平衡二叉树(AVL)
    安装apache2.4.10
    centos下编译安装mysql5.6
    随机 I/O & 顺序 I/O
    什么是mysql中的元数据
    linux中mail函数不能发送邮件怎么办
    检测MYSQL不同步发邮件通知的脚本
    mysql自动备份策略
  • 原文地址:https://www.cnblogs.com/zhmlzhml/p/13366741.html
Copyright © 2011-2022 走看看