八皇后问题,要求输出按数值排序的前三种布局方式(用一个数组代表每行皇后放置位置),以及布局的种类。
写了两个方案,第一个为循环,第二个为递归。循环复杂度超了一点,没有通过。递归做了优化,可以通过。
两个方案都贴出来,做些对比:
方案一:循环,用一个数组保存前几行皇后摆放情况以及未放置皇后的列信息。第二种方法也是用同样的数组进行信息保存,这样做不知道算不算是个偷巧,因为这样并不能保证得到全部的布局序列的有序,但可以保证前几项是有序的,以及可以输出全部的布局序列。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
public class checker {
public static void main(String[] args) throws IOException,FileNotFoundException {
BufferedReader br = new BufferedReader(new FileReader("checker.in"));
FileWriter fout = new FileWriter("checker.out");
int dimension = Integer.parseInt(br.readLine());
LinkedList<int[]> queue = new LinkedList<int[]>();
int[] init = new int[dimension];
for(int i = 0;i<dimension;i++) {
init[i]=i;
}
queue.add(init);
long start = System.currentTimeMillis();
for(int layer=0;layer<dimension;layer++) {
int length_queue = queue.size();
for(int j =0;j<length_queue;j++) {
int[] list = queue.poll();
for(int i = layer;i<dimension;i++) {
if(isPassed(list,layer,list[i])) {
int[] tmp =list.clone();
swap(tmp,layer,i);
queue.add(tmp);
}
}
}
}
int size = queue.size();
String result = new String();
if(queue.size()>2) {
for(int i = 0;i<3;i++) {
int[] tmp = queue.poll();
for(int j = 0;j<dimension;j++){
result+=" "+(tmp[j]+1);
}
fout.write(result.substring(1)+"\n");
result = new String();
}
}
long end= System.currentTimeMillis();
System.out.println(end-start);
fout.write(size+"\n");
fout.flush();
fout.close();
log.flush();
log.close();
br.close();
System.exit(0);
}
private static void swap(int[] tmp, int k, int i) {
if(k==i) {
return;
}
int t = tmp[k];
tmp[k] = tmp[i];
tmp[i] = t;
}
private static boolean isPassed(int[] list, int layer, int value) {
for(int i = 0;i<layer;i++) {
if(list[i]==value||list[i]-value==layer-i||list[i]-value==i-layer)
return false;
}
return true;
}
}
方案二:递归,复杂度O(N!)
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
public class checker {
private static FileWriter log ;
private static int dimension;
private static int counter = 0;
public static void main(String[] args) throws IOException,FileNotFoundException {
BufferedReader br = new BufferedReader(new FileReader("checker.in"));
// FileWriter fout = new FileWriter("checker.out");
log = new FileWriter("checker.out");
dimension = Integer.parseInt(br.readLine());
LinkedList<int[]> queue = new LinkedList<int[]>();
int[] init = new int[dimension];
for(int i = 0;i<dimension;i++) {
init[i]=i;
}
queue.add(init);
long start = System.currentTimeMillis();
queen(init,0);
long end= System.currentTimeMillis();
System.out.println(end-start);
log.write(counter+"\n");
log.flush();
log.close();
br.close();
System.exit(0);
}
private static void queen(int[] column,int layer) {
if(layer==dimension) {
if(counter<3)
printer(column);
counter++;
}
for(int i =layer;i<dimension;i++) {
if(isPassed(column,layer,column[i])) {
swap(column,layer,i);
queen(column,layer+1);
swap(column,layer,i);
}
}
}
private static void printer(int[] tmp) {
try {
String result = new String();
for(int i : tmp)
result +=" "+(i+1);
log.write(result.substring(1)+"\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void swap(int[] tmp, int k, int i) {
if(k==i) {
return;
}
int t = tmp[k];
tmp[k] = tmp[i];
tmp[i] = t;
}
private static boolean isPassed(int[] list, int layer, int value) {
for(int i = 0;i<layer;i++) {
if(list[i]==value||list[i]-value==layer-i||list[i]-value==i-layer)
return false;
}
return true;
}
}