HDU 1006 Tick and Tick
阿新 • • 發佈:2018-11-01
題目概括
輸入:0~120之間的實數變數D,當D為-1時退出
輸出:鐘錶上三個指標兩兩相距大於等於D的時間佔整天時間的百分比
Sample Input
0 120 90 -1
Sample Output
100.000 0.000 6.251
分析
這個問題需要選定時間單位,採用列舉法搜尋,善用區間去除不可能情況,縮短時間消耗。參考 這裡 的思路,程式碼也是仿寫的。
首先,計算三者的角速度(°/s),這裡以 秒 為單位。
秒針: 6 °/s
分鐘:1/10 °/s
時針:1/120 °/s
那麼,兩兩之間的角速度差可以定義為:
秒針和分針 sm = 11/120 °/s
秒針和時針 sh = 719/120 °/s
分針和時針 mh = 11/120 °/s
所以,兩兩之間每相隔1°,需要的時間為:
秒針和分針 t_sm = 120/11 s
秒針和時針 t_sh = 120/719 s
分針和時針 t_mh = 120/11 s
計算出首次滿足角度D的時間和首次不滿足角度D的時間,求三者的交集,分別取最大值和最小值,就是滿足的時間。
/***************************************************************** *Name:tick and tick *Time:20180813-seaf1re 參考:https://blog.csdn.net/lianai911/article/details/42807277 由於三者會在12小時後再次相遇,選定12小時區間計算即可。 *****************************************************************/ #include <iostream> #include <stdio.h> #include <algorithm> const double sm = 59.0/10,sh = 719.0/120,mh = 11.0/120; //必須顯式寫成.0的格式,否則會存為整數 const double t_sm = 360*10.0/59,t_sh = 360*120.0/719,t_mh = 360*120.0/11; //走1°的時間 * 360 = 走一圈的時間 using namespace std; //定義最大值最小值函式 double Min(double a,double b,double c){ return min(c,min(a,b)); } double Max(double a,double b,double c){ return max(c,max(a,b)); } int main() { double D; while(cin >> D && D != -1){ double b_sm,b_sh,b_mh,e_sm,e_sh,e_mh,start,finish,sum = 0; if(D == 0){ //計算邊界情況 sum = 100; printf("%.3lf\n",100.0); continue; } //第一次滿足條件的時間 b_sm = D / sm; b_sh = D / sh; b_mh = D / mh; //第一次不滿足條件的時間 e_sm = (360 - D) / sm; e_sh = (360 - D) / sh; e_mh = (360 - D) / mh; //尋找可能的時間,求三種情況的交集.順序可交換 for (double b1 = b_sm,e1 = e_sm; e1 <= 12 * 60 * 60; b1 += t_sm , e1 += t_sm){ for (double b2 = b_sh,e2 = e_sh; e2 <= 12 * 60 * 60; b2 += t_sh , e2 += t_sh){ if(e2 < b1) continue; if(b2 > e1) break; for (double b3 = b_mh,e3 = e_mh; e3 <= 12 * 60 * 60; b3 += t_mh , e3 += t_mh){ if(e3 < b2 || e3 < b1) continue; if(b3 > e1 || b3 > e2) break; start = Max(b1,b2,b3); finish = Min(e1,e2,e3); sum += (finish - start); } } } printf("%.3lf\n",sum/(12*60*60)*100); } return 0; }