算法分析ios
秒針(S): 1s 360/60= 6 度(degree)
分針(M): 1s 360/60*60= 1/10度(degree)
時針(H): 1s 360/60*60*12= 1/120度(degree)算法
秒針與分針的相對速度爲:
V(M,S) = 6-1/10 = 59/10 d/s;
同理, 時針與秒針 V(H,S) = 6-1/120 =719/120 d/s;
V(H,M) = 1/10-1/120 = 11/120 d/s.app
秒針與分針的相遇週期爲
T(M,S)= 360/V(M,S)= 3600/59;
同理, T(H,S)= 360/V(H,S)=43200/719;
T(H,M)= 360/V(H,M)=43200/11;函數
在一天24小時內,後12個小時與前12個小時狀況徹底相同,故只取12個小時便可。
則12個小時總秒數
T = 12h * 60m* 60s = 43200sthis
秒針與分針的相遇次數爲
N(M,S)=T/T(M,S) = 59*12 = 708
同理, N(H,S)=T/T(H,S) = 719
N(H,M)=T/T(H,M) = 11spa
因爲週期性規律可知:
假設秒針與分針之間的角度用函數F(t)表示,則 F(t)爲某一時刻t兩針之間的角度。
F(t+n*T(M,S)) = F(t) , 其中n爲天然數,
同理, F(t+n*T(H,S)) = F(t)
F(t+n*T(H,M)) = F(t)指針
因此,咱們只要計算出第一個週期內的各指針之間的幸福時間區段,再加上若干個各自週期後,仍爲幸福區段。
假設角度差至少爲D時,秒針和分針才幸福,則在第一個週期T(M,S)內,
D<= V(M,S)*t <= 360-D rest
解得 t1=D/V(M,S)
t2=(360-D)/V(M,S);
根據週期性,
happy(t ms) =(t1+n*T(M,S),t2+n*T(M,S)) 0 <= n < N(M,S);
同理, happy(t hs ) =(t1+n*T(H,S),t2+n*T(H,S)) 0 <= n < N(H,S);
happy(t hm) =(t1+n*T(H,M),t2+n*T(H,M)) 0 <= n < N(H,M);code
最後,求得三者的交集區間長度blog
L = happy(t ms) X happy(t hs) X happy(t hm) ,(X表示關係交)便可。
#include <iostream> #include <iomanip> using namespace std; const int T = 360*120, NMS = 708,NHM = 11, NHS = 719; //相遇次數 const double F = 0.0466631; //F爲調節係數,使得各區間段爲準確值 const double hmlen = T*F/NHM,mslen = T*F/NMS,hslen = T*F/NHS; struct interval { double low,high; }; interval andset(interval S1,interval S2) { interval zone; zone.low = S1.low > S2.low ? S1.low : S2.low; zone.high = S1.high < S2.high ? S1.high : S2.high; if( zone.low >= zone.high ) zone.low = zone.high = 0.0; return zone; } int main() { int D=0; while(cin>>D&&D!=-1) { double len = 0.0; interval ms,hs,hm; hm.low = hmlen*D/360 - hmlen; hm.high = - hm.low -hmlen; ms.low = mslen*D/360 - mslen; ms.high = - ms.low -mslen; hs.low = hslen*D/360 - hslen; hs.high = - hs.low -hslen; for(int i=0,j=0,k=0;i<NHM;i++) { hm.low+=hmlen; hm.high+=hmlen; for(;j<NMS;j++) { ms.low+=mslen; ms.high+=mslen; interval temp1 = andset(hm,ms); if(temp1.low!=0||temp1.high!=0) { for(;k<NHS;k++) { hs.low+=hslen; hs.high+=hslen; interval temp2 = andset(temp1,hs); len+=temp2.high-temp2.low; if(hs.high>=temp1.high) { hs.low-=hslen; hs.high-=hslen; break; } } } if(ms.high>=hm.high) { ms.low-=mslen; ms.high-=mslen; break; } } } cout<<setprecision(3)<<fixed<<len/(432*F)<<endl; } return 0; }