八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
回溯法:
private static void func2(int[] ar, int k, int length) {//确定下标为k行的皇后该放的位置
if(k == length){//当k行全部排列完就可以输出了
count++;
System.out.print("第" + count +"次八皇后排列方式:");
for(int i=0; i<length; ++i){
System.out.print(ar[i] + " ");
}
System.out.println();
} else {
for(int i=k; i<length; ++i){
swap(ar, k, i);//每一次交换就想相当于给每一行确定皇后在第几列
//八皇后的全排列的过滤条件
if(line(ar, k)){
func2(ar, k+1, length);
}
swap(ar, k, i);
}
}
}
private static boolean line(int[] ar, int i) {//检测在第k行i列放置时,会不会有冲突
for(int j=0; j<i; ++j){
if(Math.abs(ar[i] - ar[j]) == Math.abs(i-j)){
//判断在对角线位置是否有冲突不用判断是否同行同列,因为是一行一行确定的位置所以,前i-1行肯定不在同一行列
return false;
}
}
return true;
}
}