#include <stdio.h> #include <string.h> #include <queue> #include <vector> #include <algorithm> using namespace std; const int dx[] = {1, 1, -1, -1, 3, 3, -3, -3}; const int dy[] = {3, -3, 3, -3, 1, -1, 1, -1}; const int px[] = {1, 1, -1, -1, 1, 1, -1, -1}; const int py[] = {1, -1, 1, -1, 1, -1, 1, -1}; int hdist[16][16][16][16]; vector< pair<int, int> > g[16][16]; int move(int n, int m, int x, int y, int kind, int &rx, int &ry) { int tx, ty; tx = x + dx[kind], ty = y + dy[kind]; if (tx < 0 || ty < 0 || tx >= n || ty >= m) return 0; rx = tx, ry = ty; tx = x, ty = y; return 1; } void moveBfs(int n, int m, int sx, int sy) { int x, y, tx, ty; int dist[16][16] = {}; const int INF = 0x3f3f3f3f; queue<int> X, Y; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) dist[i][j] = INF; X.push(sx), Y.push(sy), dist[sx][sy] = 0; while (!X.empty()) { x = X.front(), y = Y.front(); X.pop(), Y.pop(); for (int i = 0; i < 8; i++) { if (move(n, m, x, y, i, tx, ty)) { if (dist[tx][ty] > dist[x][y] + 1) { dist[tx][ty] = dist[x][y] + 1; X.push(tx), Y.push(ty); } } } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { hdist[sx][sy][i][j] = dist[i][j]; } } } #define MAXL (100>>5)+1 #define GET(x) (mark[x>>5]>>(x&31)&1) #define SET(x) (mark[x>>5] |= 1<<(x&31)) int mark[MAXL]; int P[5500], Pt = 0; void sieve() { register int i, j, k; SET(1); int n = 100; for(i = 2; i <= n; i++) { if(!GET(i)) { for (k = n/i, j = i*k; k >= i; k--, j -= i) SET(j); P[Pt++] = i; } } } int ida_depth, solved; int used[16][16]; int IDA(int x, int y, int ex, int ey, int dep, int hv) { if (hv == 0) { if (!GET(dep)) { solved = 1; return dep; } return 0x3f3f3f3f; return dep; } if (dep + hv > ida_depth) return dep + hv; int back = 0x3f3f3f3f, shv, tmp; for (int i = 0; i < g[x][y].size(); i++) { int tx = g[x][y][i].first, ty = g[x][y][i].second; shv = hdist[tx][ty][ex][ey]; if (used[tx][ty]) continue; used[tx][ty] = 1; tmp = IDA(tx, ty, ex, ey, dep + 1, shv); used[tx][ty] = 0; back = min(back, tmp); if (solved) return back; } return back; } int main() { sieve(); int n, m, sx, sy, ex, ey; int cases = 0; while (scanf("%d %d %d %d %d %d", &n, &m, &sx, &sy, &ex, &ey) == 6) { for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) moveBfs(n, m, i, j); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { g[i][j].clear(); for (int k = 0; k < 8; k++) { int tx, ty; if (move(n, m, i, j, k, tx, ty)) g[i][j].push_back(make_pair(tx, ty)); } } } printf("CASE# %d: ", ++cases); if (hdist[sx][sy][ex][ey] > 1 && hdist[sx][sy][ex][ey] < 100 && !GET(hdist[sx][sy][ex][ey])) { printf("The knight takes %d prime moves.\n", hdist[sx][sy][ex][ey]); continue; } solved = 0; if (hdist[sx][sy][ex][ey] != 0x3f3f3f3f && (sx != ex || sy != ey)) { memset(used, 0, sizeof(used)); used[sx][sy] = 1; ida_depth = 0; for (int i = 0; i < Pt && P[i] < 11; i++) { if (P[i] < ida_depth) continue; ida_depth = P[i]; ida_depth = IDA(sx, sy, ex, ey, 0, hdist[sx][sy][ex][ey]); if (solved) { printf("The knight takes %d prime moves.\n", P[i]); break; } } } if (!solved) { if (hdist[sx][sy][ex][ey] == 0x3f3f3f3f) printf("Destination is not reachable.\n"); else printf("The knight takes %d composite move(s).\n", hdist[sx][sy][ex][ey]); } } return 0; } 5 7 2 2 3 1 5 5 0 0 3 4 5 5 0 0 4 4 5 5 0 0 0 0 8 4 4 0 3 2 4 8 1 1 3 5 5 7 2 2 3 1 7 8 0 7 0 5 7 5 1 4 0 4 5 6 1 4 0 2 6 4 0 2 0 1 8 8 1 0 2 7 8 5 0 1 6 1 7 8 1 5 1 4 */
|