java 递归 8皇后问题,8个皇后有关问题 java递归可以算出

8个皇后问题 java递归可以算出

背景:"八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。"——百度百科

2221258305.jpg

--40357162 (需要先理解这个数列 8个数列,列值0-7;每个结果都由0,1,2,3,4,5,6,7组成.)

通过分析问题,不难发现一个序列只要符合两点要求,就可实现8颗皇后的同盘并存:

1)序列L中第n元素L[n]的本身值不能和其前任意元素L[i]的本身值相等,即:L[n] != L[i | (0, n-1)];

2)序列L中任意元素L[n]的本身值与其前任意元素L[i]的本身值之差的绝对值,不能和L[n]的位置值n与L[i]的位置值i之差的绝对值相等,即:| L[n] - L[i] | != |n - i|, 0 <= i <= n-1;

2221258306.jpg

再加上边界限制条件,我们就可以利用以上两条原则来构造递归结构。

其实不仅仅是八皇后问题,10皇后,18皇后,甚至100皇后都符合这两条规则,所以我们可以把问题引申为求解 “N Queens Puzzle”。

实例代码(全):

import java.util.ArrayList;

public class test1 {

private static ArrayList al = new ArrayList();

private static ArrayList record = new ArrayList();

private static int MAX = 0;

private static int amount = 1;

public static void main(String[] args) {

//MAX = Integer.parseInt(args[0]);

MAX = 8;

while(al.size()==0 || al.get(0)!=8){

work();

System.out.print("\n" + amount + ") ");

record.add((ArrayList)al.clone());

output(record.get(record.size()-1));

al.remove(al.size()-1);

endAddOne();

amount++;

}

}

private static void work(){

int i = 0;

while(al.size() < MAX){

if( isOK(al, i)){

al.add(i);

i = 0;

}

else{

if( i < MAX-1 ){

i++;

}

else{

endAddOne();

i = 0;

}

}

}

}

//only check the last one of the arraylist;

//could not be like: either | al[i] - a | == | i - a | or al[i] == a;

//if not satisfied, returns a false;

//else returns a true;

private static boolean isOK(ArrayList al, int a){

int size = al.size();

if(size < 1) return true;

if(size <= MAX){

for(int i=0; i

if(a == al.get(i) || Math.abs((a - al.get(i))/(float)(size - i)) == 1){

return false;

}

}

return true;

}

return false;

}

private static void endAddOne(){

if(al.size()==0){

System.exit(1);

}

int last = al.get(al.size()-1) + 1;

if(last >= MAX){

al.remove(al.size()-1);

endAddOne();

}

else{

al.remove(al.size()-1);

if(isOK(al, last)){

al.add(last);

}

else{

al.add( last);

endAddOne();

}

}

}

private static void output(ArrayList al){

for(int i=0; i

System.out.print(al.get(i) + " ");

}

}

}

输出结果:

1) 0 4 7 5 2 6 1 3

2) 0 5 7 2 6 3 1 4

3) 0 6 3 5 7 1 4 2

4) 0 6 4 7 1 3 5 2

5) 1 3 5 7 2 0 6 4

6) 1 4 6 0 2 7 5 3

7) 1 4 6 3 0 7 5 2

8) 1 5 0 6 3 7 2 4

9) 1 5 7 2 0 3 6 4

10) 1 6 2 5 7 4 0 3

11) 1 6 4 7 0 3 5 2

12) 1 7 5 0 2 4 6 3

13) 2 0 6 4 7 1 3 5

14) 2 4 1 7 0 6 3 5

15) 2 4 1 7 5 3 6 0

16) 2 4 6 0 3 1 7 5

17) 2 4 7 3 0 6 1 5

18) 2 5 1 4 7 0 6 3

19) 2 5 1 6 0 3 7 4

20) 2 5 1 6 4 0 7 3

21) 2 5 3 0 7 4 6 1

22) 2 5 3 1 7 4 6 0

23) 2 5 7 0 3 6 4 1

24) 2 5 7 0 4 6 1 3

25) 2 5 7 1 3 0 6 4

26) 2 6 1 7 4 0 3 5

27) 2 6 1 7 5 3 0 4

28) 2 7 3 6 0 5 1 4

29) 3 0 4 7 1 6 2 5

30) 3 0 4 7 5 2 6 1

31) 3 1 4 7 5 0 2 6

32) 3 1 6 2 5 7 0 4

33) 3 1 6 2 5 7 4 0

34) 3 1 6 4 0 7 5 2

35) 3 1 7 4 6 0 2 5

36) 3 1 7 5 0 2 4 6

37) 3 5 0 4 1 7 2 6

38) 3 5 7 1 6 0 2 4

39) 3 5 7 2 0 6 4 1

40) 3 6 0 7 4 1 5 2

41) 3 6 2 7 1 4 0 5

42) 3 6 4 1 5 0 2 7

43) 3 6 4 2 0 5 7 1

44) 3 7 0 2 5 1 6 4

45) 3 7 0 4 6 1 5 2

46) 3 7 4 2 0 6 1 5

47) 4 0 3 5 7 1 6 2

48) 4 0 7 3 1 6 2 5

49) 4 0 7 5 2 6 1 3

50) 4 1 3 5 7 2 0 6

51) 4 1 3 6 2 7 5 0

52) 4 1 5 0 6 3 7 2

53) 4 1 7 0 3 6 2 5

54) 4 2 0 5 7 1 3 6

55) 4 2 0 6 1 7 5 3

56) 4 2 7 3 6 0 5 1

57) 4 6 0 2 7 5 3 1

58) 4 6 0 3 1 7 5 2

59) 4 6 1 3 7 0 2 5

60) 4 6 1 5 2 0 3 7

61) 4 6 1 5 2 0 7 3

62) 4 6 3 0 2 7 5 1

63) 4 7 3 0 2 5 1 6

64) 4 7 3 0 6 1 5 2

65) 5 0 4 1 7 2 6 3

66) 5 1 6 0 2 4 7 3

67) 5 1 6 0 3 7 4 2

68) 5 2 0 6 4 7 1 3

69) 5 2 0 7 3 1 6 4

70) 5 2 0 7 4 1 3 6

71) 5 2 4 6 0 3 1 7

72) 5 2 4 7 0 3 1 6

73) 5 2 6 1 3 7 0 4

74) 5 2 6 1 7 4 0 3

75) 5 2 6 3 0 7 1 4

76) 5 3 0 4 7 1 6 2

77) 5 3 1 7 4 6 0 2

78) 5 3 6 0 2 4 1 7

79) 5 3 6 0 7 1 4 2

80) 5 7 1 3 0 6 4 2

81) 6 0 2 7 5 3 1 4

82) 6 1 3 0 7 4 2 5

83) 6 1 5 2 0 3 7 4

84) 6 2 0 5 7 4 1 3

85) 6 2 7 1 4 0 5 3

86) 6 3 1 4 7 0 2 5

87) 6 3 1 7 5 0 2 4

88) 6 4 2 0 5 7 1 3

89) 7 1 3 0 6 4 2 5

90) 7 1 4 2 0 6 3 5

91) 7 2 0 5 1 4 6 3

92) 7 3 0 2 5 1 6 4

此文参考自:http://xman--bsn.blog.sohu.com/38195158.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值