题目链接:https://www.luogu.com.cn/problem/P1219
代码实例:
import java.util.Scanner;
/**
* @author: 梁树鹏
*/
public class luogu2_7_1219 {
/*
* 举例说明:a[]
* a为存放每一行,皇后的位置,a[1]=6,代表第一行的皇后放在位置6,以此类推bcd
*
*/
static int a[] = new int[1000];//a存放每一行皇后的位置
static int b[] = new int[1000];//b代表每一列,是否被放置了皇后
static int c[] = new int[1000];//c存左下到右上的对角线(行+列的和相同)
static int d[] = new int[1000];//d存左上到右下的对角线(行-列的差相同),注意有负数的情况,请看下面
static int n = 0,s = 0;
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
//从第一个皇后开始搜索,即第一行
search(1);
System.out.println(s);
scanner.close();
}
//用于输出的函数
public static void print(){
int i;
s++;
if(s<=3){
for(i=1;i<=n;i++) {
System.out.print(a[i]+" ");//a存储的就是皇后的位置
}
System.out.println();
}
}
//搜索、回溯、标记
public static int search(int i){
for(int j=1;j<=n;j++) {
if(b[j]==0 && c[i+j]==0 && d[i-j+n]==0){//判断是否可以放棋子
a[i]=j;//标记i排是第j个
b[j]=1;//宣布占领纵列j
/**
* 注释:对角线d[i-j]后面必须加上一个n,因为i-j可能为负数,那么数组就会出错
* 所以将整体向右偏移n个单位(坐标偏移不会影响我们需要达到的目的)
* 将所有可能变成正数;(因为i-j的最小值是-n+1,所以加上一个n就一定会变成一个正数)
*/
c[i+j]=1; d[i-j+n]=1;//宣布占领两条对角线
if(i==n) {
print();//输出,已经放完所有皇后
} else {
search(i+1);//放置第i+1个皇后
}
b[j]=0;c[i+j]=0;d[i-j+n]=0;//回溯,对放置皇后的位置释放标记,尝试下一个位置是否可行
}
}
return 0;
}
}