本地我自己造了 9000+ 的数据跑,也没出现过什么运行时错误或者异常,但是提交上来就是 Runtime Error,实在有点搞不明白是为什么,大家有知道的么?
另外,hiho 是否可以考虑在 runtime error 的情况下给出一些更具体的信息,比如 stack overflow 之类的。
代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Scanner;
import java.io.FileInputStream;
public class hiho100 {
static int len = 9;
public static void main(String[] args) throws Exception
{
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int[] arr = new int[9];
int result;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < 9; j++)
{
arr[j] = scanner.nextInt();
}
ThreeOrderStatus s = new ThreeOrderStatus(9, arr);
result = s.search();
System.out.println(result == -1 ? "No Solution!" : result);
}
} //end main
}
class Status {
int num; //该状态在所有状态中的排序
int len;
int[] arrange = new int[len]; //该状态的全排列
public Status(int len, int num)
{
this.num = num;
this.len = len;
this.arrange = reCantor(num);
}
public Status(int len, int[] arrange)
{
this.arrange = arrange;
this.len = len;
this.num = cantor(arrange);
}
protected int cantor() {
return cantor(this.arrange);
}
protected int[] reCantor() {
return reCantor(this.num);
}
protected int cantor(int[] arrange)
{
int X = 0;
int tp;
int len = arrange.length;
for(int i = 0; i < len; i++)
{
tp = 0;
for(int j = i + 1; j < len; j++)
{
if(arrange[j] < arrange[i]) tp++;
}
X += tp * factorial(len - i - 1);
}
return X;
}
private int factorial(int j)
{
if(j == 0) return 1;
int sum = 1;
for(int i = j; i > 0; i--) sum *= i;
return sum;
}
protected int[] reCantor(int num)
{
int len = this.len;
int X = num;
int cnt;
int[] arrange = new int[len];
boolean[] used = new boolean[len];
for(int i = 0; i < len; i++) used[i] = false;
for(int i = 0; i < len; i++)
{
arrange[i] = X / factorial(len - 1 - i);
X = X % factorial(len - 1 -i);
cnt = 0;
for(int j = 0; j < len; j++)
{
if(!used[j])
{
cnt += 1;
if(cnt == arrange[i] + 1)
{
arrange[i] = j;
used[j] = true;
break;
}
}
}
}
return arrange;
}
public int getNum()
{
return this.num;
}
public int[] getArrange()
{
return this.arrange;
}
}
//三阶,即九宫格,其状态
class ThreeOrderStatus extends Status {
int g; //实际步数
int h; //估值函数
int f; //总和
static int[] lastStatus = {1,2,3,4,5,6,7,8,0}; //最终状态
public boolean equals(Object o)
{
if(!(o instanceof ThreeOrderStatus)) return false;
if(o == null) return false;
ThreeOrderStatus e = (ThreeOrderStatus) o;
if(this.num != e.num) return false;
return true;
}
public int hashCode()
{
return this.num;
}
public ThreeOrderStatus(int len, int num)
{
super(len, num);
}
public ThreeOrderStatus(int len, int arrange[])
{
super(len, arrange);
}
// 获取某个状态的邻居状态
public ArrayList getNeighbors()
{
int num = this.num;
ArrayList neighbors = new ArrayList();
int index = -1;
int[] arrange = reCantor(num);
for(int i = 0; i < this.len; i++)
{
if(arrange[i] == 0)
{
index = i;
break;
}
}
if(index % 3 ==0)
{
if(indexValid(index - 3)) neighbors.add(exchange(arrange, index, index - 3));
if(indexValid(index + 3)) neighbors.add(exchange(arrange, index, index + 3));
neighbors.add(exchange(arrange, index, index + 1));
} else if(index % 3 == 1) {
if(indexValid(index - 3)) neighbors.add(exchange(arrange, index, index - 3));
if(indexValid(index + 3)) neighbors.add(exchange(arrange, index, index + 3));
neighbors.add(exchange(arrange, index, index + 1));
neighbors.add(exchange(arrange, index, index - 1));
} else {
if(indexValid(index - 3)) neighbors.add(exchange(arrange, index, index - 3));
if(indexValid(index + 3)) neighbors.add(exchange(arrange, index, index + 3));
neighbors.add(exchange(arrange, index, index - 1));
}
return neighbors;
}
private boolean indexValid(int index)
{
if(index < 0 || index > 8) return false;
return true;
}
private int exchange(int[] arrange, int index1, int index2)
{
int[] arrangeTmp = new int[9];
for(int i = 0; i < 9; i++)
{
arrangeTmp[i] = arrange[i];
}
arrangeTmp[index1] = arrange[index2];
arrangeTmp[index2] = arrange[index1];
return cantor(arrangeTmp);
}
//计算h
public int calH()
{
int h = 0;
int index1 = 0;
int index2 = 0;
for(int i = 0; i < 9; i++)
{
for(int k = 0; k < 9; k++){
if(arrange[k] == i) index1 = k;
if(lastStatus[k] == i) index2 = k;
}
h += calManhDis(index1, index2);
}
return h;
}
private int calManhDis(int index1, int index2)
{
int y1 = index1 / 3;
int x1 = index1 % 3;
int y2 = index2 / 3;
int x2 = index2 % 3;
return Math.abs(y1 - y2) + Math.abs(x1 - x2);
}
//主要部分,查找
public int search()
{
PriorityQueue openList = new PriorityQueue(new ThreeOrderStatusComparator());
HashSet openListAssist = new HashSet();
//LinkedList closeList = new LinkedList();
HashSet closeListAssist = new HashSet();
ThreeOrderStatus start = this;
start.g = 0;
start.h = start.calH();
start.f = start.g + start.h;
openList.add(start);
openListAssist.add(start.num);
ThreeOrderStatus u, j;
ArrayList neighbors = null;
ThreeOrderStatus lastStatus = new ThreeOrderStatus(9, ThreeOrderStatus.lastStatus);
while(openList.size() != 0)
{
u = openList.poll();
openListAssist.remove(u.num);
//closeList.add(u);
closeListAssist.add(u.num);
if(u.equals(lastStatus)) return u.f;
neighbors = u.getNeighbors();
for(Integer k : neighbors)
{
j = new ThreeOrderStatus(len, k);
if(openListAssist.contains(j.num))
{
j.f = j.f > j.h + u.g + 1 ? j.h + u.g + 1 : j.f;
} else if(closeListAssist.contains(j.num)) {
continue;
} else {
j.g = u.g + 1;
j.h = j.calH();
j.f = j.g + j.h;
openList.add(j);
openListAssist.add(j.num);
}
}
} //end while
return -1;
}
}
class ThreeOrderStatusComparator implements Comparator
{
public int compare(ThreeOrderStatus x, ThreeOrderStatus y)
{
if(x.f > y.f) return 1;
if(x.f < y.f) return -1;
return 0;
}
}