八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。
根据8皇后摆放位置的要求,可以看出就是一个字符串重排的问题。可以将8*8象棋格子认为是2个包含8个元素的数组。其中一个数组表示水平方向的位置,而另外一个表示竖直方向上的位置。而将行看成不变的数组来标记皇后放的位置,因此对其中一个数组进行全排列就能够保证任意两个皇后肯定不同行不同列。接下来,我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==ColumnIndex[i]-Column[j]或者j-i==ColumnIndex[i]-ColumnIndex[j]。 下面是代码实现:
package Stringchar;
public class QueenPermu {
int num = 0;
public void Permutation(int[] ColumnIndex, int index, int length) {
if (index == length) {
if (CheckQueen(ColumnIndex, length)) {
++num;
PrintQueen(ColumnIndex, length);
}
} else {
for (int i = index; i < length; i++) {
int temp = ColumnIndex[i];
ColumnIndex[i] = ColumnIndex[index];
ColumnIndex[index] = temp;
Permutation(ColumnIndex, index + 1, length);
temp = ColumnIndex[index];
ColumnIndex[index] = ColumnIndex[i];
ColumnIndex[i] = temp;
}
}
}
public void PrintQueen(int[] columnIndex, int length) {
System.out.println("满足八皇后的第%d个摆放位置为:" + num);
for (int i = 0; i < length; i++)
System.out.print(columnIndex[i] + " ");
System.out.println();
}
public boolean CheckQueen(int[] columnIndex, int length) {
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if ((i - j == columnIndex[i] - columnIndex[j])
|| (j - i == columnIndex[i] - columnIndex[j]))
return false;
}
}
return true;
}
public void EightQueen() {
int queens = 8;
int columnIndex[] = new int[queens];
for (int i = 0; i < queens; i++)
columnIndex[i] = i;
Permutation(columnIndex, 0, queens);
}
public static void main(String[] args) {
QueenPermu queenPermu=new QueenPermu();
queenPermu.EightQueen();
}
}