N皇后問題-位保存狀態思維

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; 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章