您的位置:首页 > 其它

八皇后问题(可改为N皇后)递归

2014-02-23 14:53 169 查看

N皇后问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 6816    Accepted Submission(s): 3092


[align=left]Problem Description[/align]
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。

你的任务是,对于给定的N,求出有多少种合法的放置方法。

 

[align=left]Input[/align]
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
 

[align=left]Output[/align]
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
 

[align=left]Sample Input[/align]

1
8
5
0

 

[align=left]Sample Output[/align]

1
92
10

 

[align=left]Author[/align]
cgf
 

[align=left]Source[/align]
2008 HZNU Programming Contest 
方法一:

本算法直接打印出那些皇后的位置

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;
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: