题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4255
本题有一个小trick,虽说给定的数的范围是[1,10000],但有可能存在一条绕出100*100的矩阵(包含1-10000的数的矩阵)的从起点到达终点的路径,比完全位于100*100矩阵(包含1-10000的数的矩阵)当中的从起点到达终点的最短路径的长度还要短,于是,便要扩大矩阵,为特殊情况的搜索另外开辟一条路。
#include <cstdio>
#define ny i+dy[(dir+k)%4]
#define nx j+dx[(dir+k)%4]
const int N = 106;
const int M = 13000;
const int inf = (int)1e9;
const int dx[4] = {0, 1, 0, -1}; // 0 down 1 right 2 up 3 left
const int dy[4] = {1, 0, -1, 0};
int a[N][N];
int dist[N][N];
int x[M], y[M];
int prm[M>>1], pn;
bool np[M];
void getprm()
{
np[0] = np[1] = true;
pn = 0;
prm[pn++] = 2;
for(int i=2; i<M; i++) {
if(!np[i]) prm[pn++] = i;
for(int j=0; j<pn; j++) {
if(i*prm[j] >= M) break;
np[i*prm[j]] = true;
if(i%prm[j] == 0) break;
}
}
}
int main()
{
getprm();
int flag = 1;
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) a[i][j] = inf;
}
int dir = 0;
a[N/2][N/2-1] = 1;
int b = 2;
int i = N/2, j = N/2-1;
while(flag) {
flag = 0;
for(int k=1; k>=0; k--) {
if(ny>=0 && nx>=0 && nx<N && ny<N) {
if(a[ny][nx] == inf) {
a[ny][nx] = b++;
i = ny, j = nx;
dir = (dir+k)%4;
flag = 1;
break;
}
}
}
if(!flag) break;
}
int xxx, yyy, num = 1, xi, xj, vi, vj;
while(~scanf("%d%d", &xxx, &yyy)) {
printf("Case %d: ", num);
num++;
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
if(a[i][j] == xxx) {
xi = i, xj = j;
dist[i][j] = 0;
}
else {
if(a[i][j] == yyy) {
vi = i, vj = j;
}
dist[i][j] = inf;
}
}
}
y[1] = xi, x[1] = xj;
int b=1, e=1, flag1 = 0;
while(b <= e) {
for(int j=0; j<4; j++) {
int xk = x[b] + dx[j];
int yk = y[b] + dy[j];
if(xk>=0 && yk>=0 && xk<N && yk<N) {
if(np[a[yk][xk]] && dist[yk][xk] == inf) {
e++;
x[e] = xk;
y[e] = yk;
dist[yk][xk] = dist[y[b]][x[b]] + 1;
if(yk == vi && xk == vj) { flag1 = 1; break; }
}
}
}
if(flag1) break;
b++;
}
if(dist[vi][vj] == inf) printf("impossible\n");
else printf("%d\n", dist[vi][vj]);
}
return 0;
}