这道题目确实是挺难想的——对于我而言,如果不看别人的思路,我也是想不出的。
我现在采用的思路是:
枚举国王和骑士们相遇的地点(最多26*30),及可能会带上国王的好心骑士及他们相遇的地点(坐标)。
呵呵……这就得想明白一点,如下图所示
如果某个骑士要去接国王,那么应该这个骑士应到国王附近一格距离(图中蓝色部分)或国王当前所在坐标位置(图中红色部分)。
当然也要考虑国王自己跑到终点的情况。
下面是我代码,仅供参考:
/* ID: guo geer PROG: camelot LANG: C++ */ #include<iostream> #include<cstring> #include<string> #include<cstdio> #include<fstream> #include<cmath> using namespace std; int kingMove [9][2] = {{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 0}}; int knightMove [8][2] = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}}; int dist[27][31][27][31]; int knightLocation[2000][2]; void bfs(int board[][31], int x0, int y0, int X, int Y) { int f, r, r1; int q[10000][2]; q[0][0] = x0, q[0][1] = y0; board[x0][y0] = 0; f=r=r1=0; int steps = 1; while(true) { r ++; while(f != r) { int x, y; for(int i=0; i<8; i++) { x = q[f][0]+knightMove[i][0]; y = q[f][1]+knightMove[i][1]; if(x>0 && x<=X && y>0 && y<=Y && board[x][y] == -1) { q[++r1][0] = x; q[r1][1] = y; board[x][y] = steps; } } f++; } steps ++; if(r1 < r) return ; r = r1; } } int main() { freopen("camelot.in", "r", stdin); freopen("camelot.out", "w", stdout); int x0, y0, X, Y; char ch; scanf("%d %d", &Y, &X); scanf(" %c %d", &ch, &y0); x0 = ch-'A'+1; memset(dist, -1, sizeof(dist)); for(int i=1; i<=X; i++) for(int j=1; j<=Y; j++) bfs(dist[i][j], i, j, X, Y); int x, y; int n = 0; while(scanf(" %c %d", &ch, &y) != EOF) { x = ch-'A'+1; knightLocation[n][0] = x; knightLocation[n][1] = y; n ++; } int res = 1000000; for(int i=1; i<=X; i++) { for(int j=1; j<=Y; j++) { int s0 = 0; int isAllPositive = 1; for(int k=0; k<n; k++) { int tx, ty; tx = knightLocation[k][0]; ty = knightLocation[k][1]; s0 += dist[i][j][tx][ty]; if(dist[i][j][tx][ty] < 0) isAllPositive = 0; } if(isAllPositive == 0) continue; for(int k=0; k<n; k++) { int tx, ty; tx = knightLocation[k][0]; ty = knightLocation[k][1]; for(int dir=0; dir<9; dir++) { int x1 = kingMove[dir][0]+x0; int y1 = kingMove[dir][1]+y0; if(x1 < 1 || x1 > X || y1 < 1 || y1 > Y) continue; if(dist[i][j][tx][ty] < 0 || dist[i][j][x1][y1] < 0 || dist[x1][y1][tx][ty] < 0) continue; int s = s0 - dist[i][j][tx][ty] + dist[i][j][x1][y1] + dist[x1][y1][tx][ty]; if(dir != 8) s ++; if(res > s) res = s; } if(res > max(abs(x0-tx),abs(y0-ty))+s0) res = max(abs(x0-tx),abs(y0-ty))+s0; } } } if(n == 0) res = 0; printf("%d\n", res); return 0; }