提交了15次,一直超时。后来参考别人的解题思路,和自己的做了对比,复杂度一致,差在一个常数倍上。
采用BFS算法,和别人的想法有些不太一样。
用一个树来代表全部有效的操作步骤,从根到每个叶的路径为一个有效的操作,每个节点的value为一个二维数组,数组的第一个元素代表该节点子节点值的取值下限,如若为4,则第一个子树的值应当为4,第二个为5,一次类推;第二个元素代表从根节点到本节点第一个元素值出现的次数,若次数达到3次,则子树的取值下限增1,如若[3,3],则第一个子树取值为[4,1]。
用BFS遍历该树可以保证得到的操作步骤是按照数值递增的,这样在获得第一个有效的路径时即可以结束遍历。
树结构如下:
方法说明:pre_process()对每个操作进行预处理,每步转换成相应位为011的二进制码。
process()按照相应method转动相应钟表。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
public class clocks {
private static final String[] MOVES = { "ABDE", "ABC", "BCEF", "ADG",
"BDEFH", "CFI", "DEGH", "GHI", "EFHI" };
private static int[][] iMOVES;
private static final int FULL = (1 << 27) - 1;
private static int[] optimal_steps ;
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
BufferedReader br = new BufferedReader(new FileReader("clocks.in"));
FileWriter fout = new FileWriter("clocks.out");
String init = new String();
for (int i = 0; i < 3; i++) {
init += " "+br.readLine() ;
}
int clocks =pre_process( init);
//0:move;1:counter;2:clocks;3-11:times of each method
int[] moves = new int[12];
moves[2] = clocks;
// Define three Queue
LinkedList<int[]> queue = new LinkedList<int[]>();
// Initial queues
queue.add(moves);
while (queue.size() > 0) {
int[] move = queue.poll();
int clock = move[2];
if (clock == 0) {
optimal_steps =move;
break;
}
if (move[1] == 3 && move[0] == 8)
continue;
if (move[1] < 3) {
int[] moves_tmp = move.clone();
int clocks_tmp=process(clock, move[0]);
moves_tmp[1]++;
moves_tmp[2]=clocks_tmp;
moves_tmp[move[0]+3]++;
queue.add(moves_tmp);
}
for (int i = (int)move[0] + 1; i < 9; i++) {
int[] moves_tmp = move.clone();
int clocks_tmp =process(clock, i);
moves_tmp[0] = i;
moves_tmp[1] = 1;
moves_tmp[2] = clocks_tmp;
moves_tmp[i+3]++;
queue.add(moves_tmp);
}
}
//output result
if (optimal_steps == null)
fout.write("NONE\n");
else {
StringBuffer result = new StringBuffer();
for(int i =0;i<9;i++) {
for(int j =0;j<optimal_steps[i+3];j++) {
result.append((i+1)+" ");
}
}
fout.write(result.substring(0,result.length()-1) + "\n");
}
fout.flush();
fout.close();
br.close();
long end = System.currentTimeMillis();
System.out.println(end- start);
System.exit(0);
}
private static int pre_process(String init) {
String[] str = init.substring(1).split(" ");
int clock = 0;
int counter = 0;
for (int i = 0; i < 9; i++) {
clock += (((Integer.parseInt(str[i]) / 3) & 3)<< (3 * i) );
if (clock != 0) {
counter++;
}
}
iMOVES = new int[9][3];
for(int i =0;i<9;i++) {
char[] chars = MOVES[i].toCharArray();
for(char c: chars) {
iMOVES[i][0] += (1<<((c-'A')*3));
}
iMOVES[i][2] = iMOVES[i][0]+(iMOVES[i][0]<<1)+(iMOVES[i][0]<<2);
iMOVES[i][1] = iMOVES[i][0]+(iMOVES[i][0]<<1);
}
return clock;
}
/**
* @descrpition:apply method in clocks.
*
* */
private static int process(int clocks, int method) {
return (((clocks&iMOVES[(int)method][2])+iMOVES[(int)method][0])&iMOVES[(int)method][1])+(clocks&(FULL-iMOVES[(int)method][2]));
}
}