8皇后问题,2n皇后

八皇后问题

做三个个布尔类型数组分别记录列(column)和斜对角线的使用情况,主要问题在于斜对角线如何标记。

仔细观察发现,每个斜对角线的斜率相同,而且斜率分别为1,-1.先讨论斜率为-1的情况,直线方程应为y=x+ ?,直接观察可得方程为y=-x+4.斜率为1时同理可得y=x-2.(数组中注意x轴是竖直的,y轴是横向的,所以算方程应将其逆时针旋转90度)

代码如下:


import java.util.Scanner;

public class L4 {

	static char[][] map = new char[10][10];
	static boolean[] column = new boolean[10];
	static boolean[] x1 = new boolean[20];
	static boolean[] x2 = new boolean[20];
	static int n, ans = 0;

	static boolean check(int row, int i) {
		return !column[i] && !x1[row + i] && !x2[row - i + 8];
	}

	static void dfs(int row) {
		if (row == 8) {
			ans++;
			if (ans <= 2) {
				System.out.println("==========");
				show();
			}
			return;
		}
		for (int i = 0; i < 8; i++) {
			if (check(row, i)) {
				column[i] = x1[row + i] = x2[row - i + 8] = true;
				map[row][i] = '#';
				dfs(row + 1);
				column[i] = x1[row + i] = x2[row - i + 8] = false;
				map[row][i] = '.';
			}
		}
	}

	static void show() {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				System.out.print(map[i][j]);
			}
			System.out.println();
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		n = 8;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				map[i][j] = '.';
			}
		}
		dfs(0);
		System.out.println(ans);
	}

}

======================================分割线===========================================

问题描述

  给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

输入格式

  输入的第一行为一个整数n,表示棋盘的大小。

  接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

输出格式

  输出一个整数,表示总共有多少种放法。

样例输入

4

1 1 1 1

1 1 1 1

1 1 1 1

1 1 1 1

样例输出

2

样例输入

4

1 0 1 1

1 1 1 1

1 1 1 1

1 1 1 1

样例输出

0

 代码如下:

import java.util.Scanner;

public class L7 {

	static int n, ans;
	static int[][] map = new int[10][10];
	static int[] vy = new int[10];
	static int[] vd1 = new int[20];
	static int[] vd2 = new int[20];

	static void dfs(int x, int p) {
		if (x == n && p == 2) {
			ans++;
			return;
		}
		if (x == n) {
			dfs(0, p + 1);
			return;
		}
		for (int i = 0; i < n; i++) {// 一次为1,二次为3,所以要多判断3一下
			if (map[x][i] != 0 && vy[i] != p && vd1[x + i] != p && vd2[x - i + n] != p && vy[i] != 3 && vd1[x + i] != 3
					&& vd2[x - i + n] != 3) {
				map[x][i] = 0;
				vy[i] = vy[i] + p;
				vd1[x + i] = vd1[x + i] + p;
				vd2[x - i + n] = vd2[x - i + n] + p;
				dfs(x + 1, p);
				map[x][i] = 1;
				vy[i] = vy[i] - p;
				vd1[x + i] = vd1[x + i] - p;
				vd2[x - i + n] = vd2[x - i + n] - p;
			}
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				map[i][j] = sc.nextInt();
			}
		}
		dfs(0, 1);
		System.out.println(ans);
	}

}

猜你喜欢

转载自blog.csdn.net/qq_41921315/article/details/88011007
今日推荐