首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

HDU Tick and Tick:三針相對運動週期分析

     編輯:C++ 入門

HDU Tick and Tick - 時鐘三針同時快樂的時間比例

三針(時、分、秒)每秒移動。若任意兩針夾角 ≥ 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 避免精度問題
  • 一天 = 12小時 = 43200秒(時針走一圈)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved