1.什麼是N皇后問題?
在nxn的棋盤上面所有的皇后不能相互攻擊,通俗的講就是所有的皇后既不在同一行也不在同一列,不在同一對角線。
2.思路
利用遞歸,逐行窮舉每一行可能的皇后位置,窮舉的同時用32位整數的位保存對應位置是否可用的情況,如下代碼:
row存當前行因與前面的皇后同列導致不可用的所有位置,
ld存當前行因與前面的皇后同左對角線導致不可用的位置,
rd存當前行因與前面的皇后同右對角線導致不可用的位置
最後將row,ld,rd位與即可得到當前行所有不可用的位置,注意處理溢出,溢出原因下面給出。
與BIT相似的是,這裏用 i&-i 取出每一個二進制位值p,然後進行深層遞歸,row|p自然就是新的row,至於ld和rd在|p之後分別左右移1即可,之前的溢出處理也就是由於這裏的移位。
3.解決代碼
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
const int n=8;
long sum = 0, upperlim = (1 << n) - 1;;
void test(long row,long ld,long rd)
{
if(row!=upperlim){
long pos=upperlim&~(row|ld|rd);
while(pos){
long p=pos&-pos;
pos-=p;
test(row|p,(ld|p)<<1,(rd|p)>> 1);
}
}
else sum++;
}
int main(int argc, char *argv[])
{
time_t tm=time(0);
test(0,0,0);
printf("%d皇后問題共有%ld種排列,計算時間%d秒 \n",n,sum,(int)(time(0)-tm));
return 0;
}