029棋盘挑战(经典暴搜问题—八皇后问题)

题目描述: 给定一个 N×N的棋盘,请你在上面放置 N个棋子,要求满足:

  • 每行每列都恰好有一个棋子
  • 每条对角线上都最多只能有一个棋子 029棋盘挑战(经典暴搜问题—八皇后问题)_第1张图片
    上图给出了当 N=6 时的一种解决方案,该方案可用序列 2 4 6 1 3 5
    来描述,该序列按顺序给出了从第一行到第六行,每一行摆放的棋子所在的列的位置。 请你编写一个程序,给定一个 N×N的棋盘以及
    N个棋子,请你找出所有满足上述条件的棋子放置方案。

输入格式:

共一行,一个整数 N。

输出格式:

共四行,前三行每行输出一个整数序列,用来描述一种可行放置方案,序列中的第 i个数表示第 i行的棋子应该摆放的列的位置。
这三行描述的方案应该是整数序列字典序排在第一、第二、第三的方案。 第四行输出一个整数,表示可行放置方案的总数。

数据范围:

6≤N≤13

输入样例:

6

输出样例:

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

对于八皇后问题:搜索顺序是依次搜索每一行的棋子放到哪个位置上。
029棋盘挑战(经典暴搜问题—八皇后问题)_第2张图片029棋盘挑战(经典暴搜问题—八皇后问题)_第3张图片
注意以下几个问题:
1.要按字典序输出,但是dfs可以保证天然的字典序
2.恢复现场:不同分支不要相互影响到
3.如何判断某些位置能不能填?
对于列:可以开个布尔数组;
对于对角线:可以给正反对角线序号,保证相同对角线编号相同,不同对角线编号不同。

import java.util.Scanner;

//棋盘挑战
public class Main{
     
	static int N = 15;
	static int n;
	static boolean[] col = new boolean[N];//列
	//对角线有2N-1条
	static boolean[] dg = new boolean[N * 2];//正对角线
	static boolean[] udg = new boolean[N * 2];//反对角线
	static int[] path = new int[N];//记录方案
	static int ans;//记录方案数
	public static void dfs(int x) {
     //x表示行数
		//如果x大于n表示已经填完了前n行,说明已经找到了一个方案
		if(x > n) {
     
			ans++;
			if(ans <= 3) {
     
				for(int i = 1; i <= n;i++) {
     
					System.out.print(path[i] + " ");
				}
				System.out.print("\n");
			}
			return;
		}
		for(int y = 1; y <= n;y++) {
     //枚举对于当前行要填到哪一列
			if(!col[y] && !dg[x+y] && !udg[y-x+n]) {
     //保证第y列没有数,并且x和y所在对角线没有数
				path[x] = y;
				col[y] = dg[x+y] = udg[y-x+n] = true;
				dfs(x+1);//搜索下一行
				//以下两行在恢复现场
				col[y] = dg[x+y] = udg[y-x+n] = false;
				path[x] = 0;
			}
		}
	}
	public  static void main(String[] args) {
     
		Scanner read = new Scanner(System.in);
		n = read.nextInt();
		dfs(1);
		System.out.println(ans);
	}
}

你可能感兴趣的:(算法,dfs,算法,java,八皇后)