2020 icpc 沈阳 I

题目

source

题解

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

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

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

[Delta heta le frac{2pi A}{MH} ]

[Delta heta ge 2pi - frac{2pi 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) eq 1),那么有

[Tfrac{H-1}{d} mod frac{MH}{d} le lfloor frac{A}{d} floor \ Tfrac{H-1}{d} mod frac{MH}{d} ge lceil frac{MH-A}{d} ceil \ ]

这里是因为

[Acdot B le C Leftrightarrow A le lfloor frac{C}{B} floor \ Acdot B ge C Leftrightarrow A ge lceil frac{C}{B} ceil ]

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

[d cdot (lfloor frac{A}{d} floor+1+frac{MH}{d}-lceil frac{MH-A}{d} ceil) ]

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

#include <bits/stdc++.h>
 
#define endl '
'
#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;
}
原文地址:https://www.cnblogs.com/limil/p/15362929.html