这个是在(1)的基础上进行一点改进
关于八皇后的第一种解法:八皇后问题(1)
因为第一种解法只是利用了不同行,并没有利用不同列的条件,所以会增加不必要的遍历,所以这个算法在开始就将皇后的位置规定为不能 重复,可以减少递归的次数,此时问题也将变为将八个不同的位置全排列,所以问题变为了全排列。
代码如下
import java.util.Vector;
public class Main2 {
public static int coun = 0;
//将s中的数据全排列到r中
public static void queen(Vector<Integer> s, Vector<Integer> r) {
//当 将s中的数据全排列到r中时递归结束 并且输出r中数据
if (s.size() == 0) {
show(r);
return;
}
else {
for (int i = 0; i < s.size(); i++) {
Vector<Integer> sou = new Vector<Integer>(s);
Vector<Integer> res = new Vector<Integer>(r);
res.add(sou.remove(i));
//在全排列的基础上增加一个判读,来过滤同对角线的情况
if (isOk(res)) {
queen(sou, res);
}
}
}
}
//输出
private static void show(Vector<Integer> r) {
coun++;
for (int i = 0; i < r.size(); i++) {
System.out.println((i + 1) + " hang " + (r.get(i) + 1) + " lie");
}
System.out.println();
}
//判断当前的排列情况是否满足题意,此时只需要判断对角线即可
private static boolean isOk(Vector<Integer> res) {
if (res.size() == 1) {//就一个数据时不用判断
return true;
}
//因为用的向量 所以下标从零开始并且size代表的是长度,而不是最后一个元素 所以判断的表达式有点臃肿
for (int i = 0; i < res.size() - 1; i++) {
if (Math.abs(i - (res.size() - 1)) == Math.abs(res.get(i)
- res.get(res.size() - 1))) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int n = 8;
Vector<Integer> sou = new Vector<Integer>();
Vector<Integer> res = new Vector<Integer>();
for (int i = 0; i < n; i++) {
sou.add(i);
}
queen(sou, res);
System.out.println(coun);
}
}