N皇后问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6816 Accepted Submission(s): 3092
Problem Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
Author
cgf
Source
方法一:
本算法直接打印出那些皇后的位置
import java.util.Scanner;
public class 八皇后 {//方法一
static int n,C[];
static boolean vis[][];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
n = sc.nextInt();
C = new int [10];
dfs(1);
}
}
/**@param args cur:行方向
*@param args i:列方向
*@param args C[x](x:行、C[x]:皇后所在列)
*C[cur]-cur==C[j]-j:代表负对角线方向相等
*C[cur]+cur==C[j]+j:代表正对角线方向相等
**/
private static void dfs(int cur) {
if(cur==n+1){
for(int x=1;x<=n;x++)
System.out.print(" ("+x+","+C[x]+")");
System.out.println();
}else for(int i=1;i<=8;i++)//代表列
{
int ok = 1;
C[cur]=i;
for(int j=1;j<cur;j++)//检查前面cur-1中的其中之一的皇后冲突
if((C[cur]==C[j]||C[cur]-cur==C[j]-j||C[cur]+cur==C[j]+j)){
ok = 0;
break;
}
if(ok==1)dfs(cur+1);
}
}
}
方法二:
import java.util.Scanner;
public class 八皇后 {//效率更高,用vis[3][]来标记列向、正对角线、负对角线以存在皇后
static int n,C[];
static boolean vis[][];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
n = sc.nextInt();
C = new int [n+1];//改一下即为n皇后
vis = new boolean[3][100];//需要写上100否则空指针
dfs(1);
}
}
/**
@param args cur:行方向
*@param args i:列方向
*@param args C[x](x:行、C[x]:皇后所在列)
*vis[0][i]:代表纵向
*vis[1][i-cur+n]:代表负对角线方向
*vis[2][cur+i] :代表正对角线方向
*
**/
private static void dfs(int cur) {
if(cur==n+1){
for(int x=1;x<=n;x++)
System.out.print(" ("+x+","+C[x]+")");
System.out.println();
}else for(int i=1;i<=n;i++)//代表列
{
if(!vis[0][i]&&!vis[1][i-cur+n]&&!vis[2][cur+i]){//找一个位置没有冲突的
C[cur] = i;//记下皇后所在行列
vis[0][i]=vis[1][i-cur+n]=vis[2][cur+i]=true;
dfs(cur+1);
vis[0][i]=vis[1][i-cur+n]=vis[2][cur+i]=false;
}
}
}
}