标签:算法
早上起来想着给自己出一道算法题,想到最近看到的八皇后问题,就上网搜资料,也照着前人写的算法自己敲了一边,我认为结构很清晰,递归回溯就很方便地解决了这个问题。现在贴上代码和注释,供自己回顾总结。
一.问题描述:
在n*n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。
输入:
给定棋盘的大小n
输出:
所有放置方法
二.解题思路:
要解决N皇后问题,就是要解决怎么摆放N个皇后的位置,即每一个皇后不能与前面所有皇后处在同一行、同一列或同一斜线。N行要放N个皇后,还不能在同一行,显然每行只能放置一个皇后,那么我们就可以把这个作为已知条件,只考虑每一列该怎么放,显然需要且仅需要满足两个条件:
1.不能与前面所有皇后处在同一列
2.不能与前面所有皇后处在同一斜线。
数据结构可以用一个ArrayList<Integer>存放一个满足条件的摆放位置,即仅需要记录每行的列数,行数就是ArrayList<Integer>.size()。所有满足条件的摆放位置也可以用一个ArrayList<String>表示,即每个满足条件的摆放位置的toString()结果。详细算法请看代码:
package code;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 使用递归回溯算法解决N皇后问题
* @author chenhaiyue
* 2014年11月26日10:50:47
*/
public class NQueen {
public static void main(String[] args) {
ArrayList<Integer> array = new ArrayList<Integer>();
ArrayList<String> arrayResult = new ArrayList<String>();
int n = 11;
returnNQueen(array, arrayResult, n);
System.out.println("总的解个数为:" + arrayResult.size());
Iterator<String> itr = arrayResult.iterator();
for (; itr.hasNext();) {
System.out.println(itr.next());
}
}
/**
* 计算N皇后问题的所有解
* @param array 当前所有皇后的摆放位置
* @param arrayResult 所有可行解的集合
* @param n
*/
private static void returnNQueen(ArrayList<Integer> array,
ArrayList<String> arrayResult, int n) {
//如果得到一个解,就把它放到所有解的集合
if (array.size() == n) {
arrayResult.add(array.toString());
}
for (int i = 0; i < n; i++) {
if (checkNQueen(array, i)) {
array.add(i);
returnNQueen(array, arrayResult, n);
array.remove(array.size()-1);
}
}
}
/**
* 检查第K行皇后摆放位置是否可行,两种情况不可行。1:在同一列已经存在皇后 2:在对角线上已经存在皇后
* @param array 当前所有皇后的摆放位置
* @param k 第K行
* @return
*/
private static boolean checkNQueen(ArrayList<Integer> array, int k) {
int n = array.size();
for (int i = 0; i < n; i++) {
//第一种情况
if (k == array.get(i))
return false;
//第二种情况
if (n - i == Math.abs(k - array.get(i)))
return false;
}
return true;
}
}
标签:算法
原文地址:http://blog.csdn.net/chy996633/article/details/41512701