zoukankan      html  css  js  c++  java
  • [位运算] n皇后

    一般解法

    • 算法思路:

      • 对于所有的位置,判断能不能放;

      • 能放就放,处理;

      • 不可行,回溯;

    • 剪枝:

      • 不能在同一行

      deep++;

      • 不能在同一列

      • 不能在同一斜线

        check k;
        for(i = 1; i <= deep; i++)
            col[i] != k; //同行
            abs(i - deep) != abs(col[i] - k);//同斜线
        

    二进制解法

    row : 置1的位置表示当前列被占用 , 如 0 0 0 0 1

    ld : 置1的位置表示当前左斜线被占用 , 如 0 0 0 1 0

    rd : 置1的位置表示当前右斜线被占用 , 如 0 0 0 0 0

    0 0 0 0 0        0 0 0 0 1        0 0 1 0 1        1 0 1 0 1
    0 0 0 0 0  --->  0 0 0 1 0  --->  0 1 1 0 0  --->  1 1 0 0 0 
    0 0 0 0 0        0 0 0 0 0        0 0 0 1 0        0 1 0 0 1
    
    0 0 0 0 0        0 0 0 1 1        0 1 1 1 1        1 1 1 0 1
    
    1 1 1 1 1        1 1 1 0 0        1 0 0 0 0        0 0 0 1 0
            .            .            .                      .
    
    // 从右侧的列开始 向左判
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <stack>
    #include <deque>
    #include <iostream>
    using namespace std;
    typedef long long LL;
    const LL N = 200009;
    
    int check, sum;
    
    void test(int row, int ld, int rd)
    {
        int pos, p;
        if (row != check)
        {
            pos = check & ~(row | ld | rd);   //获得所有可以放的位置
    
            while (pos)    //从右向左尝试所有可以放的位置
            {
                p = pos & (~pos + 1);  // 获得当前最右侧的位置
                pos -= p;              // 标记该位置
    
                test(row + p, (ld + p) << 1, (rd + p) >> 1);  // 把该位加到列上去,把该位加到斜线上去后 整体平移  
            }
        }
        else
        {
            sum++;
        }
    }
    
    int main()
    {
        int i, j, n;
        int a[15];
        for (i = 1; i <= 10; i++)
        {
            check = (1 << i) - 1;
            sum = 0;
            test(0, 0, 0);
            a[i] = sum;
        }
    
        
        while(scanf("%d", &n) != EOF && n )
        {
            printf("%d
    ", a[n]);
        }
        return 0;
    }
    
    

    已知两点,求所经过直线的斜率:

    k = (x2 - x1) / (y2 - y1)
    
  • 相关阅读:
    Weekly blog for week 1908
    Weekly blog for week 1907
    Weekly blog for week 1905&1906
    Weekly blog for week 1904
    Write Week 3 Blog beforehand
    Add Week 2 Blog
    First week of a new year
    Andriod-Log
    bat
    学习方法
  • 原文地址:https://www.cnblogs.com/daybreaking/p/11757516.html
Copyright © 2011-2022 走看看