算法学习 八皇后问题的递归实现 java版 回溯思想
1.问题描述
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
2.思路分析
回溯法:当把问题分成若干步骤并递归求解时,如果当前步骤没有合法的选择时,则函数即调用上一层的递归,此即为回溯。
在每次的正向递归时是一个试探的过程,将本次的影响带入到下一次的递归过程中去,如果在下一次的函数中,并没有找到一个合适的解去调用在下一层的函数,则证明上一次的函数过程产生了不正确的中间结果,这个结果使得整个函数不能被正确执行了,所以此时应返回对于全局变量的影响(如果产生了如果有必要,回溯法的过程中大多数是有必要返回这个影响的),然后再次去试探。。。一直到达递归的出口。
八皇后问题的思路即:
1):以行的方式去摆放棋子
2):在每次的试探摆放时,检查是否有以前的棋子与本次拟摆放的位置相冲突,(由于是按行摆放,故只需验证是否有同一列和同一对角线即可)
3): 如果产生了冲突,则返回上一层的调用
4):如果产生了符合条件的位置,则进入下一行的判断
package lianxi;
import java.util.Scanner;
public class EightQueen {
static int tol = 0,n;
static int C[] ;
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
n = scan.nextInt();
C = new int[n];
for(int j=0;j<n;j++){
C[j] = 0;
}
search(0);
System.out.println(tol);
}
private static void search(int cur) {
if(cur == n){
tol++;
System.out.println("第"+tol+"种放法:");
for(int i = 0;i< n;i++){
for(int i1 = 0;i1< n;i1++){
if(C[i] == i1)
System.out.print('Q');
else
System.out.print('+');
}
System.out.println();
}
System.out.println();
}else {
for(int j = 0;j<n;j++){
int ok = 1;
C[cur] = j;
for(int k = 0;k<cur ;k++){
if(C[k] == C[cur] || C[k] - k ==C[cur]-cur || C[cur] + cur == C[k] + k ){
//C[k] - k ==C[cur]-cur C[cur] + cur == C[k] + k分别用于判断是否有与当前位置处于右下对角线和左下对角线的皇后
ok = 0;
break;
}
}
if(ok==1)search(cur+1);
}
}
}
}