在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1
8
5
0
Sample Output
1
92
10
之前看过书上那个八皇后的,是用一个二维数组模拟棋盘,然后逐行只代入一个皇后分析,判断代入的皇后的那一列,的每一行有没有皇后(皇后所在行就不判断了,因为已经定好一行只有一个皇后),和判断左对角和右对角有没有皇后,如果满足就继续下一行放,不满足就拿走这个皇后回退到上一步。
再回到这个题,N皇后就是把88数组换成NN,动态分配二维数组那个int arr=new int[N]应该可以吧,好像有点麻烦,然后看到这个题N小于10,直接就设个1010算了。。。so vegetable
#include<iostream>
using namespace std;
int N,count;
int arr[10][10];
bool check(int row,int col)
{
//行肯定是没有冲突的,只检查列
for(int i=0;i<=row;i++)
{
if(arr[i][col]==1) return false;
}
//再检查对角,这是左对角
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--)
{
if(arr[i][j]==1) return false;
}
//右对角
for(int i=row-1,j=col+1;i>=0&&j<N;i--,j++)
{
if(arr[i][j]==1) return false;
}
return true;
}
void search(int row)
{
if(row==N)
{
count++;
return;
}
for(int i=0;i<N;i++)
{
if(check(row,i))
{
arr[row][i]=1;
search(row+1);
arr[row][i]=0;
}
}
}
int main(){
while(cin>>N)
{
if(N==0) break;
count=0;
search(0);
cout<<count<<endl;
}
return 0;
}
VJ上过不了阿超时了。。。哎先基本学个回溯的思想吧,之后有空再看看改进的方法,好像一共有四种???
-----------------------------------分割线----------------------------
马上到OJ去偷师了一下哈哈哈,居然还有把答案放到数组里直接输出答案的狗血方法。。。
还是要认真copy了个代码瞧瞧
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a[110][110],ver[110],L[110],R[110]; ///竖线,左斜线,右斜线
int ans ;
void dfs(int i,int n){
if(i==n){
ans ++;
return ;
}
for(int j = 0;j<n;j++){
if(!ver[j] && !L[i-j+n] && !R[i+j] ){
ver[j] = L[i-j+n] = R[i+j] = 1;
dfs(i+1,n);
ver[j] = L[i-j+n] = R[i+j] = 0;
}
}
}
int main(){
int n ;
///int ans[10] = {1,0,0,2,10,4,40,92,352,724};
int f[11]; ///防止数据大量计算
f[0] = 0;
for(int i = 1;i<=10;i++){
ans = 0;
dfs(0,i);
f[i] = ans;
}
while(cin >> n){
if(n==0)
break;
cout << f[n] << endl;
}
}