题目链接:uva 503 - Parallelepiped walk
恶心题,将三维转成两维,直线距离最短,WA了一天。假设起点在地面,除了考虑经过0,1个面的可能,还要考虑经过两个面到达的可能。后面提供一个生成数据的代码。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const ll inf = 0x3f3f3f3f3f3f3f3f; struct Point { ll x, y; Point (ll x = 0, ll y = 0): x(x), y(y) {} }; ll Dis (Point a, Point b) { ll x = a.x - b.x; ll y = a.y - b.y; return x * x + y * y; } ll solve (int L, int W, int H, int x1, int y1, int z1, int x2, int y2, int z2) { ll ans = inf; if (x2 == 0) { ans = min(ans, Dis(Point(x1, y1), Point(-z2, y2))); ans = min(ans, Dis(Point(x1, y1), Point(y2-W, z2+W))); ans = min(ans, Dis(Point(x1, y1), Point(-y2, -z2))); ans = min(ans, Dis(Point(x1, y1), Point(z2-H, 2*W+H-y2))); ans = min(ans, Dis(Point(x1, y1), Point(z2-H, -(H+y2)))); } if (x2 == L) { ans = min(ans, Dis(Point(x1, y1), Point(L+z2, y2))); ans = min(ans, Dis(Point(x1, y1), Point(L+W-y2, z2+W))); ans = min(ans, Dis(Point(x1, y1), Point(L+y2, -z2))); ans = min(ans, Dis(Point(x1, y1), Point(L+H-z2, -(H+y2)))); ans = min(ans, Dis(Point(x1, y1), Point(L+H-z2, 2*W+H-y2))); } if (z2 == 0) { ans = min(ans, Dis(Point(x1, y1), Point(x2, y2))); } if (z2 == H) { ans = min(ans, Dis(Point(x1, y1), Point(-(H+x2), y2))); ans = min(ans, Dis(Point(x1, y1), Point(-(H+y2), -x2))); ans = min(ans, Dis(Point(x1, y1), Point(-(W+H-y2), W+x2))); ans = min(ans, Dis(Point(x1, y1), Point(2*L+H-x2, y2))); ans = min(ans, Dis(Point(x1, y1), Point(L+W+H-y2, L+W-x2))); ans = min(ans, Dis(Point(x1, y1), Point(L+H+y2, x2-L))); ans = min(ans, Dis(Point(x1, y1), Point(L+H+x2, 2*W+L-y2))); ans = min(ans, Dis(Point(x1, y1), Point(L+H+x2, -(L+y2)))); } return ans; } int main () { int L, W, H, x1, y1, z1, x2, y2, z2; while (scanf("%d%d%d%d%d%d%d%d%d", &L, &W, &H, &x1, &y1, &z1, &x2, &y2, &z2) == 9) { ll ans = inf; for (int i = 0; i < 2; i++) { if (x1 == 0) { ans = min(ans, solve(W, H, L, y1, z1, x1, y2, z2, x2)); ans = min(ans, solve(H, W, L, z1, y1, x1, z2, y2, x2)); } else if (x1 == L) { ans = min(ans, solve(W, H, L, y1, z1, L-x1, y2, z2, L-x2)); ans = min(ans, solve(H, W, L, z1, y1, L-x1, z2, y2, L-x2)); } else if (y1 == 0) { ans = min(ans, solve(L, H, W, x1, z1, y1, x2, z2, y2)); ans = min(ans, solve(H, L, W, z1, x1, y1, z2, x2, y2)); } else if (y1 == W) { ans = min(ans, solve(L, H, W, x1, z1, W-y1, x2, z2, W-y2)); ans = min(ans, solve(H, L, W, z1, x1, W-y1, z2, x2, W-y2)); } else if (z1 == 0) { ans = min(ans, solve(L, W, H, x1, y1, z1, x2, y2, z2)); ans = min(ans, solve(W, L, H, y1, x1, z1, y2, x2, z2)); } else if (z1 == H) { ans = min(ans, solve(L, W, H, x1, y1, H-z1, x2, y2, H-z2)); ans = min(ans, solve(W, L, H, y1, x1, H-z1, y2, x2, H-z2)); } swap(x1,x2), swap(y1, y2), swap(z1, z2); } printf("%lld\n", ans); } return 0; } /* Data */ /* using namespace std; const int D = 1000; int main () { int cas = 1000; while (cas--) { int L[3]; L[0] = rand() % D + 1, L[1] = rand() % D + 1, L[2] = rand() % D + 1; printf("%d %d %d ", L[0], L[1], L[2]); for (int i = 0; i < 2; i++) { int k = rand() % 3; for (int j = 0; j < 3; j++) { if (k == j) printf("%d ", (cas&1 ? L[j] : 0)); else printf("%d ", rand() % L[j] + 1); } } printf("\n"); } return 0; } */