import java.util.*;
public class aaa {
private static int num=0;
public boolean place(State s,int temp,int i,int n){
for(int k=0;k<n;k++){
if(k==temp){
continue;
}
if(s.selected[k]==0){
break;
}
if(s.selected[k]==i||Math.abs(k-temp)==Math.abs(s.selected[k]-i)){
return false;
}
}
return true;
}
public class State {
int[] selected;
public State(int[] selected) {
this.selected = selected;
}
}
public void bfs(int n) {
Queue<State> queue = new LinkedList<>();
int[] init = new int[n];
State initstate = new State(init);
queue.add(initstate);
num++;
while (!queue.isEmpty()) {
State currentstate = queue.poll();
boolean flag = true;
int ivalue=-1;
for (int i = 0; i < n; i++) {
if (currentstate.selected[i] == 0) {
ivalue=i;
flag = false;
break;
}
}
if(flag){
for(int i=0;i<n;i++){
System.out.print(currentstate.selected[i]+" ");
}
System.out.println();
}
if(ivalue==-1){
continue;
}
for (int j = 1; j < n + 1; j++) {
int[] newcurrent = currentstate.selected.clone();
newcurrent[ivalue] = j;
State newcurrentstate = new State(newcurrent);
if(place(newcurrentstate,ivalue,newcurrentstate.selected[ivalue],n)){
queue.add(newcurrentstate);
num++;
}
}
}
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int n=in.nextInt();
in.close();
aaa test=new aaa();
test.bfs(n);
System.out.println(num);
}
}
运行结果:
输入:
4
输出:
2 4 1 3
3 1 4 2
17
优先队列修改:
说到底,也就是修改一下队列实现,让其比较器自动按照优先值排一下序,也就是多这两个而已。
PriorityQueue<State> queue = new PriorityQueue<>((s1, s2) -> {
int count1 = countNonZero(s1.selected);
int count2 = countNonZero(s2.selected);
return Integer.compare(count2, count1);
});
private int countNonZero(int[] array) {
int count = 0;
for (int num : array) {
if (num != 0) {
count++;
}
}
return count;
}
import java.util.*;
public class aaa {
private static int num = 0;
public boolean place(State s, int temp, int i, int n) {
for (int k = 0; k < n; k++) {
if (k == temp) {
continue;
}
if (s.selected[k] == 0) {
break;
}
if (s.selected[k] == i || Math.abs(k - temp) == Math.abs(s.selected[k] - i)) {
return false;
}
}
return true;
}
public class State {
int[] selected;
public State(int[] selected) {
this.selected = selected;
}
}
public void bfs(int n) {
PriorityQueue<State> queue = new PriorityQueue<>((s1, s2) -> {
int count1 = countNonZero(s1.selected);
int count2 = countNonZero(s2.selected);
return Integer.compare(count2, count1);
});
int[] init = new int[n];
State initstate = new State(init);
queue.add(initstate);
num++;
while (!queue.isEmpty()) {
State currentstate = queue.poll();
boolean flag = true;
int ivalue = -1;
for (int i = 0; i < n; i++) {
if (currentstate.selected[i] == 0) {
ivalue = i;
flag = false;
break;
}
}
if (flag) {
for (int i = 0; i < n; i++) {
System.out.print(currentstate.selected[i] + " ");
}
System.out.println();
}
if (ivalue == -1) {
continue;
}
for (int j = 1; j < n + 1; j++) {
int[] newcurrent = currentstate.selected.clone();
newcurrent[ivalue] = j;
State newcurrentstate = new State(newcurrent);
if (place(newcurrentstate, ivalue, newcurrentstate.selected[ivalue], n)) {
queue.add(newcurrentstate);
num++;
}
}
}
}
private int countNonZero(int[] array) {
int count = 0;
for (int num : array) {
if (num != 0) {
count++;
}
}
return count;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
in.close();
aaa test = new aaa();
test.bfs(n);
System.out.println(num);
}
}
结果还是一样,
4
3 1 4 2
2 4 1 3
17
但是如果不是找到全部,只是找到一个的话,肯定是优先队列快,
下面我们进行分析:
优先队列:
4
3 1 4 2
入队数量:14
出队数量:13
6
3 6 2 5 1 4
入队数量:48
出队数量:43
普通队列:
4
2 4 1 3
入队数量:17
出队数量:16
6
2 4 6 1 3 5
入队数量:153
出队数量:150
现在我们再看找全部,如果是六皇后:
优先队列:
6
3 6 2 5 1 4
5 3 1 6 4 2
4 1 5 2 6 3
2 4 6 1 3 5
入队数量:153
出队数量:153
普通队列:
6
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
5 3 1 6 4 2
入队数量:153
出队数量:153