标签:算法
早上起来想着给自己出一道算法题,想到最近看到的八皇后问题,就上网搜资料,也照着前人写的算法自己敲了一边,我认为结构很清晰,递归回溯就很方便地解决了这个问题。现在贴上代码和注释,供自己回顾总结。
一.问题描述:
在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