在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
思路:对于这种经典问题,必须得搞懂,记在脑子里
用一个一维数组,a[col]=row,下标表示行,值表示列
仔细想想也就是一个二重循环,外边行,里边列,当然咱们不可能用二重循环,太麻烦了,怎么记住已经放过的行和列
具体的看看代码
import java.util.Arrays;
import java.util.Scanner;
public class Main{
static int cnt;
static int a[]=new int[15];//a[col]=row;
static int sum[]=new int[15];
public static void dfs(int row,int n){
if(row==n+1){
cnt++;
return;
}
else{
for(int i=1;i<=n;i++){
if(a[i]!=0) continue;//如果第i列已经放置皇后就不能再放
a[i]=row;//当前列放置皇后
//判断是否可以放在当前位置
boolean ok=true;
for(int j=1;j<=n;j++){//判断第i列能不能放
if(i==j) continue;//本身不需要再比较
if(a[j]==0) continue;//当前列没有放置数字,没有影响
if(a[i]-a[j]==Math.abs(i-j)){//两个对角线不允许放置两个皇后
ok=false;
break;
}
}
if(ok) dfs(row+1,n);//如果当前可以放置,继续下一行
a[i]=0;//要把此列清空,为了能判断下一种方案
}
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
//预处理求出所有结果
for(int i=1;i<=10;i++){
Arrays.fill(a, 0);
cnt=0;
dfs(1,i);
sum[i]=cnt;
}
while(scan.hasNext()){
int n=scan.nextInt();
if(n==0) break;
System.out.println(sum[n]);
}
}
}