Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 1264 | Accepted: 588 |
Description
Input
Output
Sample Input
D4A3A8H1H8
Sample Output
10
Source
/* http://acm.pku.edu.cn/JudgeOnline/problem?id=1178 枚举 + floyd */ #include <iostream> #include <string> #include <cmath> #define MAX_N 64 #define MAX_VAL 100000 #define maxv(a, b) ((a) >= (b) ? (a) : (b)) #define minv(a, b) ((a) <= (b) ? (a) : (b)) using namespace std; int dir[8][2] = {{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}, {1, -2}, {2, -1}, {2, 1}, {1, 2}}; int distK[2][MAX_N + 1][MAX_N + 1]; int pos[MAX_N + 1][2]; int num = 0; bool inRange(int row, int col) { return row >= 0 && row < 8 && col >= 0 && col < 8; } //初始化格子之间的最短距离, 同时将骑士可走的格子之间的距离设置为1 void init() { int i, j, k, nr, nc, p1, p2; for(i = 0;i < MAX_N; i++) for(j = 0; j < MAX_N; j++) { if(i == j) distK[0][i][j] = distK[1][i][j] = 0; else distK[0][i][j] = distK[1][i][j] = MAX_VAL; } for(i = 0; i < 8; i++) { for(j = 0; j < 8; j++) { for(k = 0; k < 8; k++) { nr = i + dir[k][0]; nc = j + dir[k][1]; if(inRange(nr, nc)) { p1 = i * 8 + j; p2 = nr * 8 + nc; distK[0][p1][p2] = 1; } } } } } //计算任意两个格子之间的最短距离 void floyd() { int i, j, k, dij, dik, dkj, last = 0, cur; for(k = 0; k < MAX_N; k++) { cur = 1 - last; for(i = 0; i < MAX_N; i++) { for(j = 0; j < MAX_N; j++) { if(i == j) continue; dij = distK[last][i][j]; dik = distK[last][i][k]; dkj = distK[last][k][j]; if(dij < MAX_VAL && dij <= dik + dkj) distK[cur][i][j] = dij; else if(dik + dkj < MAX_VAL && dik + dkj < dij) distK[cur][i][j] = dik + dkj; else distK[cur][i][j] = MAX_VAL; } } last = cur; } } void getRes() { int res = MAX_VAL; int i, j, k, distS, d1, d2, row, col; //枚举最终的交汇点 for(i = 0; i < MAX_N; i++) { distS = 0; //计算所有骑士到这个点的距离总和 for(j = 1; j < num; j++) distS += distK[0][i][pos[j][0] * 8 + pos[j][1]]; //枚举所有国王可能和骑士的相遇点 for(j = 0; j < MAX_N; j++) { row = j / 8; col = j - row * 8; //d1是国王到j位置的距离 d1 = maxv(abs(pos[0][0] - row), abs(pos[0][1] - col)); //枚举所有骑士,寻找 这个骑士到j的距离再加上从j到i的距离然后减去骑士到i距离的最小值 d2 = MAX_VAL; for(k = 1; k < num; k++) { int curd = 0; //p为骑士的位置 int p = pos[k][0] * 8 + pos[k][1]; curd = distK[0][p][j] + distK[0][j][i] - distK[0][p][i]; if(curd < d2) d2 = curd; } //distS + d1 + d2是当前总的距离 res = minv(res, distS + d1 + d2); } } cout<<res<<endl; } int main() { int i; string input; cin>>input; num = input.length() / 2; for(i = 0; i < num; i++) { pos[i][1] = input[i * 2] - 'A'; pos[i][0] = input[i * 2 + 1] - '1'; } init(); floyd(); getRes(); return 0; }