问题描述:
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
hdu 网站直达
经典回溯法(非递归):
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
//经典算法:n皇后问题
//回溯法
public class TestNQueen {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
solveNQueens(n);
}
static int[] a;//存储皇后的位置--a[0]=1表示第一行第二列(0,1)位置有一个皇后
private static void solveNQueens(int n) {
// TODO Auto-generated method stub
init(n);//初始化棋盘
int i=0,j=0,k=0;
while(i<n){
while(j<n){
a[i] = j;
if(valid(i)){
j=0;//找下一行的第一列做比较
break;
}else{
a[i] = -1;
++j;//比较这一行的下一列
}
}
if(a[i]==-1){//如果该行未被放置皇后
if(i==0){
break;//此刻已经回溯到第一行
}else{
--i;//回溯
j=a[i]+1;//比较上一行的下一列
a[i]=-1;
continue;
}
}
if(i==n-1){ //表示已经找到最后一行
System.out.println("解法"+(++k)+":");
// list.add(print());//打印
print();
--i;//回溯
j=a[i]+1;//比较上一行的下一列
a[i]=-1;
continue;
}
i++;
}
// return list;
}
//打印n皇后
private static void print() {
// TODO Auto-generated method stub
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" "); //观察a[]数组的元素值
}
System.out.println();
System.out.println("-----以下是皇后的位置----");
// List<String> list = new ArrayList<String>();
for(int i=0;i<a.length;i++){
for(int j=0;j<a.length;j++){
if(a[i]!=j){
System.out.print(". ");
// list.add(".");
}else{
System.out.print("Q ");
// list.add("Q");
}
}
System.out.println();
}
System.out.println();
// return list;
}
//判断(i,j)位置是否合法
private static boolean valid(int i) {
// TODO Auto-generated method stub
for(int k=0;k<i;k++){
if( a[i] == a[k] || Math.abs(i-k) == Math.abs(a[i]-a[k])){
return false;
}
}
return true;
}
private static void init(int n) {
// TODO Auto-generated method stub
a = new int[n];
for(int i=0;i<n;i++){
a[i] = -1; // i对应行,a[i]对应列
}
}
}
DFS解法:
import java.util.Scanner;
//经典算法:n皇后问题
//dfs解法
public class TestNQueen {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
init(n);
solveNQueensII(0,n);
}
static int num=0;
private static void solveNQueensII(int k,int n){
if(k==n){
num++;
// print();
return;
}else{
for(int i=0;i<n;i++){
a[k] = i;
if(valid(k)){//判断该位置是否合法
solveNQueensII(k+1,n);
}
}
}
}
private static void init(int n) {
// TODO Auto-generated method stub
a = new int[n];
for(int i=0;i<n;i++){
a[i] = -1; // i对应行,a[i]对应列
}
}
//判断(i,j)位置是否合法
private static boolean valid(int i) {
// TODO Auto-generated method stub
for(int k=0;k<i;k++){
if( a[i] == a[k] || Math.abs(i-k) == Math.abs(a[i]-a[k])){
return false;
}
}
return true;
}
}
}