做三个个布尔类型数组分别记录列(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);
}
}