问题描述

Sleeping Cup's Jump 是一种特殊的舞蹈动作,舞者需要使用尽量少的移动次数在二维舞台上从点 (x1,y1)(x_1, y_1) 移动到 (x2,y2)(x_2, y_2)。每次移动可以选择一个实数 dd 和一个角度 ϕ(π2,π2)\phi \in (-\frac{\pi}{2}, \frac{\pi}{2}),并从起始位置 (x,y)(x, y) 移动到目标位置 (x+d×ϕ,y+d×tanϕ)(x + d \times \phi, y + d \times \tan \phi)

数学性质分析

移动方式的数学表达

每次移动的位移向量为:

  • d×x=d×ϕd \times x = d \times \phi
  • d×y=d×tanϕd \times y = d \times \tan \phi

关键性质推导

将两式相除得:$\frac{d \times y}{d \times x} = \frac{\tan \phi}{\phi}$

由于 ϕ(π2,π2)\phi \in (-\frac{\pi}{2}, \frac{\pi}{2})ϕ0\phi \neq 0,有以下性质:

  1. 符号相同tanϕ\tan \phiϕ\phi 同号,因此 d×xd \times xd×yd \times y 必须同号
  2. 比值大于1:在 ϕ(π2,π2)\phi \in (-\frac{\pi}{2}, \frac{\pi}{2}) 范围内,tanϕϕ>1\frac{\tan \phi}{\phi} > 1,因此 $\lvert d \times y \rvert > \lvert d \times x \rvert$

最小移动次数判断

0 次移动

当起点和终点相同时,不需要移动: d×x=0d \times x = 0d×y=0d \times y = 0

1 次移动

当位移满足以下条件时,可以通过一次移动到达:

  1. d×x0d \times x \neq 0
  2. d×y0d \times y \neq 0
  3. $\lvert d \times y \rvert > \lvert d \times x \rvert$
  4. d×xd \times xd×yd \times y 同号

2 次移动

其他所有情况都需要两次移动,包括:

  1. dx 或 dy 为 0
  2. $\lvert d \times y \rvert \le \lvert d \times x \rvert$
  3. d×xd \times xd×yd \times y 异号

AC code:

#include <bits/stdc++.h>
using namespace std;

int main() {
    freopen("tangent.in", "r", stdin);
    freopen("tangent.out", "w", stdout);
    long long x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    long long dx = x2 - x1;
    long long dy = y2 - y1;
    if (dx == 0 && dy == 0) {
        cout << 0 << endl;
    } else if (dx != 0 && dy != 0 && (dx > 0 && dy > 0 || dx < 0 && dy < 0) && abs(dy) > abs(dx)) {
        cout << 1 << endl;
    } else {
        cout << 2 << endl;
    }
    return 0;
}