2020 icpc 沈阳 I - Rise of Shadows(思维)

题目

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;
}
posted @ 2021-10-02 22:33  limil  阅读(845)  评论(3编辑  收藏  举报