八皇后计算

来源:互联网 发布:proe散热模拟软件 编辑:程序博客网 时间:2024/05/20 18:52

看了下别的地方的源码,注释太少,直接写了一下,反过来重看了下别的实现,对比精简了下。

原先做法是,假如递归到r行,则对0-r行的所有坐标 以 列、左上、右上方向分别映射到了三个数组,看数组标记是否在三个方向上有重复的皇后。实际递归前r-1行皇后位置都是验证正确的,不用形成互相检测。

package com.superzlc;/** * 八皇后计算 * @author superzlc * */public class TestEightQueen {public static void main(String[] args) {TestEightQueen queen = new TestEightQueen();long start = System.nanoTime();queen.calc();System.out.println((System.nanoTime() - start) / 1000000f);}// 8行8列棋盘private static final int row_size = 8;private static final int col_size = 8;// 用于表示所有皇后位置,8行,每行的值是几表示在这行第几列是皇后,列范围0-7,-1表示没有皇后private int[] rows = new int[row_size];int resultIndex = 0;// 设置为皇后private void setQueen(int r, int c) {rows[r] = c;}// 判断为皇后private boolean isQueen(int r, int c) {return rows[r] == c;}// 打印结果private void printResult() {StringBuilder sb = new StringBuilder();sb.append("Result ").append(++resultIndex).append(":\n");for (int r = 0; r < row_size; r++) {for (int c = 0; c < col_size; c++)sb.append(isQueen(r, c) ? 'Q' : '.');sb.append('\n');}System.out.println(sb);}// 检测(rr, cc)位置皇后满足条件private boolean checkQueenValid(int rr, int cc) {// 按递归前rr-1行的皇后肯定是满足的,只测试rr行皇后与之前行是否冲突for (int r = 0; r < rr; r++) {// 列方向检测if (isQueen(r, cc))return false;// 左上方向检测int c_lu = cc - (rr - r); // 坐标 cc - (rr - r)if (isQueen(r, c_lu))return false;// 右上方向检测int c_ru = cc + (rr - r); // 坐标 cc + (rr - r)if (isQueen(r, c_ru))return false;}return true;}// 测试第r行满足条件private void tryRow(int r) {// 第r行皇后位置为0-7,挨次测试是否合法for (int c = 0; c < col_size; c++) {if (checkQueenValid(r, c)) { // 测试合法setQueen(r, c);if (r == row_size - 1) { // 测试合法且是最后一行,打印结果printResult();} else { // 测试合法且非最后一行,继续测试下一行tryRow(r + 1);}}}}public void calc() {tryRow(0);System.out.println("result count: " + this.resultIndex);}}


0 0
原创粉丝点击