1.问题描述:
八皇后问题,是一个古老而著名的问题,同时是回溯算法的典型案例。
该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
2.解决思路:
数组a[x]=y,其中x代表第x行,y代表第y列,解决八皇后不冲突的实质也就是:
for(int i=1;i<k;i++){
if(a[i]==a[k]||Math.abs(k-i)==Math.abs(a[k]-a[i])){
return false; //出现不符合的条件
}
}
return true;//符合条件
注:a[i]==a[k]代表列相同;Math.abs(k-i)==Math.abs(a[k]-a[i])代表
处于同一斜线上
3.代码:
(之前看到有人用for循环来写,虽然没什么问题,但若是问题改成15或20个皇后,那for循环就太多了,本文给出的代码,不论多少个皇后,代码都不用改变)
public class eightQueens {
//主函数
public static void main(String[] args) {
int n;
//输入皇后的个数
Scanner scanner=new Scanner(System.in);
System.out.print("请输入皇后个数:");
n = scanner.nextInt();//输入整形数据
int number=eightQueens.cal(n);
System.out.println("一共有"+number+"种方法");
}
private static int cal(int n) {
int count=0;
int a[];
a=new int[100];
for(int i=1;i<=n;i++){
a[i]=0;
}
int k=1;
while(k>=1){
a[k]=a[k]+1;
while(a[k]<=n&&!eightQueens.judge(k, a)){
a[k]=a[k]+1;
}
if(k==n&&a[k]<=n){
for(int j=1;j<=n;j++){
System.out.print(a[j]+" ");
}
System.out.println("");
count++;
}else if(a[k]<=n&&k<n){
k++;
}else{
a[k]=0; //回溯
k--;
}
}
return count;
}
//判断条件
private static boolean judge(int k,int a[]) {
for(int i=1;i<k;i++){
if(a[i]==a[k]||Math.abs(k-i)==Math.abs(a[k]-a[i])){
return false; //出现不符合的条件
}
}
return true;//符合条件
}
}
4.结果:
请输入皇后个数:8
1 5 8 6 3 7 2 4
1 6 8 3 7 4 2 5
1 7 4 6 8 2 5 3
1 7 5 8 2 4 6 3
2 4 6 8 3 1 7 5
2 5 7 1 3 8 6 4
2 5 7 4 1 8 6 3
2 6 1 7 4 8 3 5
2 6 8 3 1 4 7 5
2 7 3 6 8 5 1 4
2 7 5 8 1 4 6 3
2 8 6 1 3 5 7 4
3 1 7 5 8 2 4 6
3 5 2 8 1 7 4 6
3 5 2 8 6 4 7 1
3 5 7 1 4 2 8 6
3 5 8 4 1 7 2 6
3 6 2 5 8 1 7 4
3 6 2 7 1 4 8 5
3 6 2 7 5 1 8 4
3 6 4 1 8 5 7 2
3 6 4 2 8 5 7 1
3 6 8 1 4 7 5 2
3 6 8 1 5 7 2 4
3 6 8 2 4 1 7 5
3 7 2 8 5 1 4 6
3 7 2 8 6 4 1 5
3 8 4 7 1 6 2 5
4 1 5 8 2 7 3 6
4 1 5 8 6 3 7 2
4 2 5 8 6 1 3 7
4 2 7 3 6 8 1 5
4 2 7 3 6 8 5 1
4 2 7 5 1 8 6 3
4 2 8 5 7 1 3 6
4 2 8 6 1 3 5 7
4 6 1 5 2 8 3 7
4 6 8 2 7 1 3 5
4 6 8 3 1 7 5 2
4 7 1 8 5 2 6 3
4 7 3 8 2 5 1 6
4 7 5 2 6 1 3 8
4 7 5 3 1 6 8 2
4 8 1 3 6 2 7 5
4 8 1 5 7 2 6 3
4 8 5 3 1 7 2 6
5 1 4 6 8 2 7 3
5 1 8 4 2 7 3 6
5 1 8 6 3 7 2 4
5 2 4 6 8 3 1 7
5 2 4 7 3 8 6 1
5 2 6 1 7 4 8 3
5 2 8 1 4 7 3 6
5 3 1 6 8 2 4 7
5 3 1 7 2 8 6 4
5 3 8 4 7 1 6 2
5 7 1 3 8 6 4 2
5 7 1 4 2 8 6 3
5 7 2 4 8 1 3 6
5 7 2 6 3 1 4 8
5 7 2 6 3 1 8 4
5 7 4 1 3 8 6 2
5 8 4 1 3 6 2 7
5 8 4 1 7 2 6 3
6 1 5 2 8 3 7 4
6 2 7 1 3 5 8 4
6 2 7 1 4 8 5 3
6 3 1 7 5 8 2 4
6 3 1 8 4 2 7 5
6 3 1 8 5 2 4 7
6 3 5 7 1 4 2 8
6 3 5 8 1 4 2 7
6 3 7 2 4 8 1 5
6 3 7 2 8 5 1 4
6 3 7 4 1 8 2 5
6 4 1 5 8 2 7 3
6 4 2 8 5 7 1 3
6 4 7 1 3 5 2 8
6 4 7 1 8 2 5 3
6 8 2 4 1 7 5 3
7 1 3 8 6 4 2 5
7 2 4 1 8 5 3 6
7 2 6 3 1 4 8 5
7 3 1 6 8 5 2 4
7 3 8 2 5 1 6 4
7 4 2 5 8 1 3 6
7 4 2 8 6 1 3 5
7 5 3 1 6 8 2 4
8 2 4 1 7 5 3 6
8 2 5 3 1 7 4 6
8 3 1 6 2 5 7 4
8 4 1 3 6 2 7 5
一共有92种方法
5.备注:
有问题的地方还请各位多多包含,不吝赐教。