Problem ID:1019 N皇后問題
簡單題意:在N*N的棋盤上放N個皇后,任意2個皇后不允許處在同一排,同一列,也不允許連線與棋盤邊框成45°角。給定N,求出所有的放置方法數。(正整數N<=10)
解題思路形成過程:利用深搜對行和列先後進行遍歷,記錄下當前位置之前所有行放置位置的列號。
在遍歷過程中,所有要放置的皇后必須同時滿足3個要求,即:和之前放置好的皇后不處在同一行、同一列,連線不成45°角。如果不完全符合這3個要求,則判斷如果放置在下一列是否符合要求;如果符合這3個要求,則直接到下一行從第一列開始遍歷。
當遍歷到最後一行時,當有符合要求的位置時,返回1;否則,返回0。
感想:①不要想當然,不是每一行都一定會有一個符合要求的位置。
②必須提前打表,N爲1-10,將所有結果提前儲存到數組中,否則會超時。
代碼:
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
int total;
int dfs(int rs[10],int r)//r:當前行號
{
int cnt=0;
if(r==total){
return 1;
}
for(int i=0;i<total;++i){//i:當前行的列號
int t=0;
for(int j=0;j<r;++j)//j:第j行
if(i==rs[j]||abs(i-rs[j])==r-j){//r[j]:第j行的列號
++t;
break;
}
if(t==0){
rs[r]=i;
cnt+=dfs(rs,r+1);
}
}
return cnt;
}
int main()
{
//freopen("2.txt","r",stdin);
/*while(1) //如果這樣寫會超時!
{
scanf("%d",&total);
int n,rs[10],o[10];
if(total==0)
return 0;
n=dfs(rs,0);
printf("%d\n",n);
}*/
int rs[10],o[10];
for(int i=1;i<=10;++i){
total=i;
o[i-1]=dfs(rs,0); //必須提前打表。
}
int t;
while(cin>>t){
if(t==0)
return 0;
printf("%d\n",o[t-1]);
}
}