先生成蛇型矩阵,然后再筛选出素数进行标记,最后bfs。这里要注意题目要求的1-10000的之间的数路径,但是并不代表我们只要打印到这个范围的素数,因为很可能边沿的点需要走到外面的图形来完成对短路,外围的也不要打印太多,毕竟素数的个数越到外面是越稀疏的,所以打印到40000足矣。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #include <map> #define MAXN 40000 using namespace std; int p[MAXN+5], G[205][205], hash[205][205]; int dist[1005][1005]; int N, M; struct Node { int x, y; }info; map<int, Node>mp; struct { int x, y, step; }q[1000005], pos; int front, tail, dir[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1}; void draw(int cen) { int num = (200 - 2*cen + 2) * (200 - 2*cen + 2)+1; int sx = cen, sy = cen; for (int j = sy; j < (200 - cen + 1); ++j) { G[sx][j] = --num; info.x = sx, info.y = j; mp[num] = info; } for (int i = sx; i < (200 - cen + 1); ++i) { G[i][(200 - cen + 1)] = --num; info.x = i, info.y = (200 - cen + 1); mp[num] = info; } for (int j = (200 - cen + 1); j > sy; --j) { G[(200 - cen + 1)][j] = --num; info.x = (200 - cen + 1), info.y = j; mp[num] = info; } for (int i = (200 - cen + 1); i > sx; --i) { G[i][sy] = --num; info.x = i, info.y = sy; mp[num] = info; } } void pre() { int k; for (int i = 4; i <= 40000; i += 2) { p[i] = 1; } for (int i = 3; i <= 200; i += 2) { if (!p[i]) { k = 2 * i; for (int j = i * i; j <= 40000; j += k) { p[j] = 1; } } } for (int cen = 1; cen <= 200; ++cen) { draw(cen); } } bool judge(int x, int y) { if (x < 1 || x > 200 || y < 1 || y > 200) { return false; } return true; } int bfs(int sx, int sy) { int xx, yy; front = 0, tail = 1; memset(hash, 0, sizeof (hash)); q[tail].x = sx, q[tail].y = sy; q[tail].step = 0; hash[sx][sy] = 1; while (front != tail) { pos = q[++front]; for (int i = 0; i < 4; ++i) { xx = pos.x + dir[i][0]; yy = pos.y + dir[i][1]; if (!hash[xx][yy] && judge(xx, yy) && G[xx][yy] != -1) { if (N <= 1000 && M <= 1000) { dist[N][G[xx][yy]] = pos.step + 1; } hash[xx][yy] = 1; if (G[xx][yy] == M) { return pos.step + 1; } ++tail; q[tail].x = xx, q[tail].y = yy; q[tail].step = pos.step + 1; } } } return -1; } int main() { int sx, sy, ans, ca = 0; p[1] = 1; pre(); for (int i = 2; i <= 40000; ++i) { if (!p[i]) { G[mp[i].x][mp[i].y] = -1; } } while (scanf("%d %d", &N, &M) == 2) { printf("Case %d: ", ++ca); if (N == M) { puts("0"); continue; } if ((N <= 1000 && M <= 1000) && dist[N][M]) { printf("%d\n", dist[N][M]); continue; } sx = mp[N].x, sy = mp[N].y; ans = bfs(sx, sy); if (ans != -1) { printf("%d\n", ans); } else { puts("impossible"); } } return 0; }