第一题: N皇后
问题描述
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。你的任务是,对于给定的N,求出有多少种合法的放置方法。
输入格式
输入中有一个正整数N≤10,表示棋盘和皇后的数量
输出格式
为一个正整数,表示对应输入行的皇后的不同放置数量。
样例输入
5
样例输出
10
数据规模和约定 N≤10
package 算法提高.皇后;
public class 八皇后dfs {
// 有几个皇后
static int max = 8;
static int count = 0;
static int a[] = new int[max]; // 定义皇宫的规模
public static void main(String[] args) {
// TODO Auto-generated method stub
check(0);
System.out.println("一共有" + count + "种类");
}
// dfs
static void check(int n) {
if (n == max) {// 如果n =max 则皇后位置已经放好
count++;
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
return;
}
// 否则,依次放入皇后,去试探
for (int i = 0; i < max; i++) {
// 先把当前这个皇后 n, 放到该行的第一列
a[n] = i;
// 再判断当前位置第n个皇后到后i列,是否冲突
if (hf(n)) {
check(n + 1);
}
// 如果冲突,就继续执行 a[n]= i ;将第n个皇后,放在本行后移动的一个位置
}
}
// 判断合法性
static boolean hf(int n) {
for (int i = 0; i < n; i++) {
if (a[i] == a[n] || Math.abs(n - i) == Math.abs(a[n] - a[i])) {
return false;
}
}
return true;
}
}
第二题:2n皇后
资源限制
内存限制:512.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
给定一个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 Main
{
static int sum=0;//统计符合的数目
public static void main(String[] args)
{
Scanner db=new Scanner (System.in);
int n=db.nextInt();
int arr[]=new int [n]; //皇后放置位置
int wee[][]=new int [n][n];// 接受输入时的0 1
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
wee[i][j]=db.nextInt();
queen(0, 0, arr, wee);//递归调用
System.out.println(sum);
}
public static int queen(int su, int k, int arr[], int[][] wee)
//su==0表示落子的是白皇后 为1 表示落子的是黑皇后 k表示第k个皇后
{
if(k==arr.length)//如果所有皇后都放置
{
if(su==0)//判断放置的是否是白皇后
{
arr=new int[arr.length]; //如果白皇后都被放置,初始化黑皇后的位置
queen(su+1, 0, arr, wee);
}
if(su==1)//判断放置的是否是白皇后
sum++; //统计2n皇后的放置种数
return sum;
}
for(int i=0; i<arr.length; i++)//判断第k个皇后位置(列数)行数为k
{
if(wee[k][i]==0) //如果当前位置坐标值为零,则不能放置皇后
continue;
int j;
for(j=0; j<k; j++)//前k-1个皇后位置(列数)行数 为j
if(arr[j]==i||Math.abs(arr[j]-i)==(k-j))//判断皇后之间是否存在同一列,统一对角线冲突
break;
if(j==k)//条件成立时表示第k个与之前的没有冲突
{
arr[k]=i; //第k个皇后位置
wee[k][i]=0; //将此位置即为0 表示不能再这放置皇后
queen(su, k+1, arr, wee); //递归调用下一层
wee[k][i]=1;
}
}
return sum;
}
}