八皇后回溯解法

经典问题,教科书式解题过程,可是在判断布局的合法性上徘徊了很久,逻辑一如既往的混乱,希望这只是由于太累的缘故,其实也只是为了练练手,感觉回溯那部分的代码十分好写,主要还是逻辑上的问题比较费劲。

 

 

public class EightQueen {
	private int[][] chess;
	private int[] used;//列数已用标记,在构造函数中初始化为-1
	private int length;

	public static void main(String[] args) {
		EightQueen eq = new EightQueen(4);
		eq.trial(0);

	}

	public EightQueen(int n) {
		this.chess = new int[n][n];
		this.used = new int[n];
		for (int i = 0; i < n; i++)
			used[i] = -1;
		this.length = n;
	}

	public void trial(int i) {
		//输出当前布局
		if (i == length) {
			System.out.println("——————————————");
			for (int r = 0; r < length; r++) {
				System.out.print("|");
				for (int c = 0; c < length; c++) {
					if(chess[r][c]==1)
						System.out.print(" X ");
					else
						System.out.print(" O ");
				}
				System.out.println("|");
			}
			System.out.println("——————————————");
		} else

			for (int j = 0; j < length; j++) {
				chess[i][j] = 1;//在第i行第j列放置皇后
				if (condition(i, j)) {//布局合法则把此列标记为此行的行数
					used[j] = i;
					trial(i + 1);//向下递归
				}
				//回溯
				if (used[j] == i)
					used[j] = -1;//当回溯到i行时,撤销对此行的列标记
				chess[i][j] = 0;//移走皇后

			}
	}

	public boolean condition(int i, int j) {
		boolean var = true;

		if (i > 0) {
			if (used[j] != -1) {
				var = false;//一列只能有一个皇后
			}

			else {
				if (j != 0 && j != length - 1) {
					if (chess[i - 1][j - 1] == 1 || chess[i - 1][j + 1] == 1)
						var = false;//非边界的皇后的左上对角或右上对角不能有皇后
				}
				//边界上的皇后合法性判定
				if (j == 0) {
					if (chess[i - 1][j + 1] == 1)
						var = false;
				}
				if (j == length - 1) {
					if (chess[i - 1][j - 1] == 1)
						var = false;
				}
			}
		}
		return var;
	}
	
}

你可能感兴趣的:(C++,c,C#,J#)