题目

​source​

题解

分针的转速为\(w_1=\frac{2\pi }{M}\),时针的转速为\(w_2=\frac{2\pi}{MH}\)。因此经过时间\(T\)后,角度差为


\[\Delta \theta=T(w_1-w_2) \mod 2\pi=\frac{2\pi (H-1)T}{MH} \mod 2\pi\]


这个角度的意义是从时针出发指向分针所经过的角度,这个角度可能大于\(\pi\),此时对应的真正的夹角应该是用\(2\pi\)减去这角度,因此原题转换为满足


\[\Delta \theta \le \frac{2\pi A}{MH}\]



\[\Delta \theta \ge 2\pi - \frac{2\pi A}{MH}\]


的所有\(T\)。经过一些简单的化简,即求满足


\[T(H-1) \mod HM \le A \\T(H-1) \mod HM \ge MH - A \]


的\(T\)有多少个,注意\(T\)的取值范围为\([0,MH)\)。这很关键。

假设\(d=\gcd(H-1, HM) \neq 1\),那么有


\[T\frac{H-1}{d} \mod \frac{MH}{d} \le \lfloor \frac{A}{d} \rfloor \\T\frac{H-1}{d} \mod \frac{MH}{d} \ge \lceil \frac{MH-A}{d} \rceil \\ \]


这里是因为


\[A\cdot B \le C \Leftrightarrow A \le \lfloor \frac{C}{B} \rfloor \\A\cdot B \ge C \Leftrightarrow A \ge \lceil \frac{C}{B} \rceil \]


这样一来\(\frac{H-1}{d}\)就和\(\frac{MH}{d}\)就互质了。由离散数学,这样不同的\(T\)恰好一共有\(\frac{MH}{d}\)个值了,即\([0,\frac{MH}{d})\)中每个值都能被取得。一轮下来一共有\(\lfloor \frac{A}{d} \rfloor+1\)和\(\frac{MH}{d}-\lceil \frac{MH-A}{d} \rceil\)个\(T\)符合条件。由于一共有\(d\)轮循环,故答案为


\[d \cdot (\lfloor \frac{A}{d} \rfloor+1+\frac{MH}{d}-\lceil \frac{MH-A}{d} \rceil)\]


注意,如果\(A=\frac{MH}{2}\),即\(\pi\),这样在等号部分会重复计算。故这种情况要特判断吗,此时答案为\(MH\)。

#include <bits/stdc++.h>

#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;

using namespace std;
/*-----------------------------------------------------------------*/

ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
#define INF 0x3f3f3f3f

const int N = 3e5 + 10;
const double eps = 1e-5;

ll up(ll x, ll k) {
return x / k + (x % k != 0);
}

int main() {
IOS;
ll h, m, a;
cin >> h >> m >> a;
ll d = gcd(h - 1, h * m);
if(2 * a == m * h) cout << m * h << endl;
else cout << (a / d + 1) * d + (m * h / d - up(m * h - a, d) ) * d << endl;
}