题目
样例
解题思路:
1、 首先这是一道典型的回溯问题。考察回溯算法。
2、 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。
3、 题目的思路代码中写的很详细,主要还是需要理解,多加练习。
参考代码
package com.ccl.study;
import java.util.*;
public class huanghouwenti {
static int n,count=0; //n表示棋盘的大小
static int map[][];
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
map=new int[n][n];
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
map[i][j]=sc.nextInt(); //棋盘录入
}
}
Put(0,2); //从第一行开始进行皇后的放置,2代表白皇后,3代表黑皇后
System.out.println(count); //当所有方法都寻找完成后,输出找到方法的个数
}
public static void Put(int t,int s) { //放置皇后的函数
if(t==n) { //是否是再放置最后一行
if(s==2) {
Put(0,3); //如果白皇后放置成功,则进行黑皇后的放置
}else {
count++; //说明s!=2黑皇后放置成功,找到一种放置的方法,计数器+1
}
return; //当整体放置过程结束,则进行程序的回溯
}
for(int i=0;i<n;i++) { //对每一行的值逐个进行操作
if(map[t][i]!=1)continue; //如果 位置不为1,就说明是0不符合,重新开始下一轮for循环
if(Check(t,i,s)) {map[t][i]=s;} //是否满足题目要求判断,满足的话,赋值
else {continue;} //不满足,同一行下一个位置继续判断执行新的for循环
Put(t+1,s); //下一行皇后的放置,这里要思考一下为什么要把put放在for循环里面
map[t][i]=1; //回溯法的关键,最后把位置复原,不影响当前数组的测试
}
return;
}
public static boolean Check(int t,int i,int s) { //判断是否满足题目要求的函数
for(int q=t-1;q>=0;q--) { //当前位置上方是否进行了相同皇后的放置,这行以下的还没放,不检查。
if(map[q][i]==s)return false;
}
for(int q=t-1,w=i-1;q>=0&&w>=0;q--,w--) { //检查左对角线,这行下面还没放,不检查
if(map[q][w]==s)return false;
}
for(int q=t-1,w=i+1;q>=0&&w<=n-1;q--,w++) { //检查右对角线,这行下面还没放,不检查
if(map[q][w]==s)return false;
}
return true;
}
}