三針(時、分、秒)每秒移動。若任意兩針夾角 ≥ D 度,則該針「快樂」。求一天(43200 秒)中三針同時快樂的時間百分比。0 ≤ D ≤ 120。
角速度:秒針 vs=6°/s,分針 vm=0.1°/s,時針 vh=1/120°/s。
相對角速度:
ω_sm = vs - vm = 5.9°/s,週期 T_sm = 360/5.9 = 3600/59 s
ω_sh = vs - vh = 719/120 °/s,週期 T_sh = 360/(719/120) = 43200/719 s
ω_mh = vm - vh = 11/120 °/s,週期 T_mh = 360/(11/120) = 43200/11 s
對每對針,相對角度在 [D, 360-D] 時兩針均快樂。每個相對週期內快樂時長:(360-2D)/360 * T。起始快樂時間點:D/360 * T。
用三指針掃描:維護三對針的下一個快樂區間 [HS[i], HE[i]]。當前交集為 [max(HS), min(HE)]。若 max(HS) < min(HE),累加長度。然後推進結束最早的那對針到下一個快樂區間。循環直到超過 43200 秒。
double T[3] = {360/(vm-vh), 360/(vs-vm), 360/(vs-vh)};
double HS[3] = {D/360*T[0], D/360*T[1], D/360*T[2]};
double HE[3] = {(360-D)/360*T[0], (360-D)/360*T[1], (360-D)/360*T[2]};
double happy = 0;
while (HS[1] < 43200 - D/360*T[0] && HS[2] < 43200 - D/360*T[0]) {
double ns = max(HS[0], max(HS[1], HS[2]));
double ne = min(HE[0], min(HE[1], HE[2]));
if (ne > ns) happy += ne - ns;
// 推進結束最早的區間
for (int i=0; i<3; ++i) {
if (fabs(HE[i] - ne) < 1e-15) { HS[i] += T[i]; HE[i] += T[i]; }
}
}
printf("%.3f\n", happy / 432.0); // 百分比 = happy/43200 * 100
D=0:100.000%(永遠快樂)D=120:0.000%(三針無法兩兩 ≥120°)D=90:6.251%eps=1e-15 避免精度問題