N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11505 Accepted Submission(s): 5112
Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1
8
5
0
Sample Output
1
92
10
Author
cgf
Source
Recommend
lcy
n皇后问题据说可以用排列组合解?目前还没搞懂。
这道题用dfs写,关键在怎么样记录将要放置的皇后的的同行同列同对角线是否已放置过皇后,采用visit[3][]数组记录,
如何判断是否在同一条对角线呢,主对角线方向i+j相等,副对角线方向i-j相等。
考虑每个这种搜法,每个位置都有两种可能性,放还是不放,所以会搜完整个解。
然后预处理好1到10,之后就可以直接查询了。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int visit[10][1000]; int answer=0; int n; void init() { answer=0; memset(visit,0,sizeof(visit)); } void dfs(int i,int j,int sum) { if(sum==n) { answer+=1; return; } for(int q=1;q<=n;q++) { if(visit[0][i+1+q]==0 && visit[1][i+1-q+n]==0 && visit[2][q]==0) { visit[0][i+1+q]=1; visit[1][i+1-q+n]=1; visit[2][q]=1; dfs(i+1,q,sum+1); visit[0][i+1+q]=0; visit[1][i+1-q+n]=0; visit[2][q]=0; } } } int main() { int f[15]; f[1]=1; for(n=2;n<=10;n++) { init(); for(int j=1;j<=n;j++) { visit[0][1+j]=1; visit[1][1-j+n]=1; visit[2][j]=1; dfs(1,j,1); visit[0][1+j]=0; visit[1][1-j+n]=0; visit[2][j]=0; } f[n]=answer; } int m; while(scanf("%d",&m)) { if(m==0) break; printf("%d\n",f[m]); } return 0; }
时间: 2024-11-05 16:04:45