【算法】N Queens Problem
生活随笔
收集整理的這篇文章主要介紹了
【算法】N Queens Problem
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*
** 目前最快的N皇后遞歸解決方法
** N Queens Problem
** 試探-回溯算法,遞歸實現
*/
#include "stdafx.h"
#include "iostream"
#include <math.h>
using namespace std;
#include "time.h"// sum用來記錄皇后放置成功的不同布局數;upperlim用來標記所有列都已經放置好了皇后。
long sum = 0, upperlim = 1;// 試探算法從最右邊的列開始。
void test(long row, long ld, long rd)
{if (row != upperlim){// row,ld,rd進行“或”運算,求得所有可以放置皇后的列,對應位為0,// 然后再取反后“與”上全1的數,來求得當前所有可以放置皇后的位置,對應列改為1// 也就是求取當前哪些列可以放置皇后long pos = upperlim & ~(row | ld | rd);while (pos) // 0 -- 皇后沒有地方可放,回溯
{// 拷貝pos最右邊為1的bit,其余bit置0// 也就是取得可以放皇后的最右邊的列long p = pos & -pos;// 將pos最右邊為1的bit清零// 也就是為獲取下一次的最右可用列使用做準備,// 程序將來會回溯到這個位置繼續試探pos -= p;// row + p,將當前列置1,表示記錄這次皇后放置的列。// (ld + p) << 1,標記當前皇后左邊相鄰的列不允許下一個皇后放置。// (ld + p) >> 1,標記當前皇后右邊相鄰的列不允許下一個皇后放置。// 此處的移位操作實際上是記錄對角線上的限制,只是因為問題都化歸// 到一行網格上來解決,所以表示為列的限制就可以了。顯然,隨著移位// 在每次選擇列之前進行,原來N×N網格中某個已放置的皇后針對其對角線// 上產生的限制都被記錄下來了test(row + p, (ld + p) << 1, (rd + p) >> 1);}}else{// row的所有位都為1,即找到了一個成功的布局,回溯sum++;}
}int main(int argc, char *argv[])
{time_t tm;int n =8;if (argc != 1)n = atoi(argv[1]);tm = time(0);// 因為整型數的限制,最大只能32位,// 如果想處理N大于32的皇后問題,需要// 用bitset數據結構進行存儲if ((n < 1) || (n > 32)){printf(" 只能計算1-32之間\n");exit(-1);}printf("%d 皇后\n", n);// N個皇后只需N位存儲,N列中某列有皇后則對應bit置1。//upperlim = (upperlim << n) - 1;
upperlim = long(upperlim*pow(2, n) - 1);test(0, 0, 0);printf("共有%ld種排列, 計算時間%d秒 \n", sum, (int)(time(0) - tm));system("pause");return 0;
}
?
轉載于:https://www.cnblogs.com/Areas/p/5650676.html
總結
以上是生活随笔為你收集整理的【算法】N Queens Problem的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BZOJ1795 : [Ioi2008]
- 下一篇: 100阶乘末尾有多少个零