题意
在一维空间内玩三个跳棋.
给定三个跳棋初始点的坐标 $a, b, c$ , 问它们能不能跳到结束点 $x, y, z$ .
如果能, 还要求出最少跳多少次.
$- {10} ^ 9 \le a, b, c, x, y, z \le {10} ^ 9$ .
分析
实现
#include <cstdio> #include <cstring> #include <cstdlib> #include <cctype> #include <algorithm> using namespace std; #define F(i, a, b) for (register int i = (a); i <= (b); i++) #define P(i, a, b) for (register int i = (a); i >= (b); i--) #define LL long long inline LL rd(void) { LL f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; LL x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; } inline void Order(LL &x, LL &y, LL &z) { static LL tmp[3]; tmp[0] = x, tmp[1] = y, tmp[2] = z; sort(tmp, tmp+3), x = tmp[0], y = tmp[1], z = tmp[2]; } inline void Root(LL &x, LL &y, LL &z, LL &d) { while (y-x != z-y) if (y-x < z-y) { LL D = y-x; LL c = ((z-1)-y) / D; d += c; x += c * D; y += c * D; } else { LL D = z-y; LL c = (y-(x+1)) / D; d += c; y -= c * D; z -= c * D; } } inline void Go(LL &x, LL &y, LL &z, LL d) { while (d > 0) if (y-x < z-y) { LL D = y-x; LL c = min(((z-1)-y) / D, d); d -= c; x += c * D; y += c * D; } else { LL D = z-y; LL c = min((y-(x+1)) / D, d); d -= c; y -= c * D; z -= c * D; } } int main(void) { #ifndef ONLINE_JUDGE freopen("hdu3830.in", "r", stdin); freopen("hdu3830.out", "w", stdout); #endif LL a, b, c, x, y, z; while (~scanf("%I64d", &a)) { b = rd(), c = rd(), x = rd(), y = rd(), z = rd(); Order(a, b, c), Order(x, y, z); LL ra = a, rb = b, rc = c, rs = 0; Root(ra, rb, rc, rs); LL rx = x, ry = y, rz = z, rw = 0; Root(rx, ry, rz, rw); if (ra != rx || rb != ry || rc != rz) { puts("NO"); continue; } LL res = 0; if (rs < rw) swap(a, x), swap(b, y), swap(c, z), swap(rs, rw); Go(a, b, c, rs-rw), res += (rs-rw), rs = rw; if (a == x && b == y && c == z) { puts("YES"); printf("%I64d\n", res); continue; } P(i, 60, 0) if ((1LL << i) <= rs) { Go(ra = a, rb = b, rc = c, 1LL << i); Go(rx = x, ry = y, rz = z, 1LL << i); if (ra != rx || rb != ry || rc != rz) { rs -= (1LL << i), rw -= (1LL << i); a = ra, b = rb, c = rc, x = rx, y = ry, z = rz; res += 2 * (1LL << i); } } puts("YES"), printf("%I64d\n", res+2); } return 0; }
时间: 2024-10-11 11:54:48