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\n", a[n]);
    }
    return 0;
}

已知兩點,求所經過直線的斜率:

k = (x2 - x1) / (y2 - y1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章