ZJCPC2004
题目大意:现在有一个普通时钟,有时针、分针、秒针,秒针不是一秒一秒间断走的,而是连
续走的。给你一个度数D(小于等于120°)。求:24小时中,三个指针超过这个度数的时间占所
有时间的百分比是多少。
思路:之前想的按每秒模拟一遍就可以了。没想到时间是连续的,而不是间隔的,参考了评论
区才知道怎么去做。顺便膜拜大神。。。
三个指针走的角速度:
秒针速度S = 6°/s,分针速度M = (1/10)°/s,时针速度H = (1/120)°/s
这三个指针两两之间的相对速度差为:
秒时相差S_H = (719/120)°/s,秒分相差S_M = (59/10)°/s,分时相差M_H = (120/11)°/s
相差一度需要的时间为
秒时相差SH = (120/719)s/度,秒分相差SM = (10/59)s/度,分时相差MH = (120/11)s/度
相差360°需要的时间为
秒时相差tSH = 43200.0/719,秒分相差tSM = 3600.0/59,分时相差tMH = 43200.0/11
三者之间都需要最少相差D°才能满足条件,设t为三个指针都满足条件的总时间,则t满足以下
条件:
N*SH + k1*tSH < t < tSH - N*SH +k1*tSH
N*SM + k2*tSM < t < tSM - N*SM + k2*tSM
N*MH + k3*tMH < t < tMH - N*MH + k3*tMH
先求出三指针两两之间第一次满足条件的时间和第一次不满足条件的时间。
在对两两指针之间满足条件的开始时间和结束时间进行遍历(三重循环),把所有满足条件的时
间累加起来就是所求满足条件的总时间。最后结果为:满足条件的总时间/43200*100。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; // 秒针速度 s = 6°/s 分针速度 m = 1/10° /s 时针 h = 1/120° /s const double SH = 719.0/120, SM = 59.0/10, MH = 11.0/120; const double tSH = 43200.0/719, tSM = 3600.0/59, tMH = 43200.0/11; double Min(double a,double b,double c) { return min(a,min(b,c)); } double Max(double a,double b,double c) { return max(a,max(b,c)); } int main() { double D; while(cin >> D && D!=-1) { double bSH,bSM,bMH,eSH,eSM,eMH,Begin,End,Sum = 0; bSH = D / SH; bSM = D / SM; bMH = D / MH; //计算第一次满足条件的时间(开始时间) eSH = (360-D)/SH; eSM = (360-D)/SM; eMH = (360-D)/MH; //计算第一次不满足条件的时间(结束时间) for(double b3 = bSH,e3 = eSH; e3 <= 43200.000001; b3+=tSH,e3+=tSH) { for(double b2 = bMH,e2 = eMH; e2 <= 43200.000001; b2+=tMH,e2+=tMH) { if(e2 < b3) //判断是否有交集 continue; if(b2 > e3) break; for(double b1 = bSM,e1 = eSM; e1 <= 43200.000001; b1+=tSM,e1+=tSM) { if(e1 < b2 || e1 < b3) continue; if(b1 > e2 || b1 > e3) break; Begin = Max(b1,b2,b3); //开始时间取最大,以满足全部要求 End = Min(e1,e2,e3); //结束时间取最小,以满足全部要求 Sum += (End-Begin); } } } printf("%.3lf\n",Sum/432); } return 0; }
原文:http://blog.csdn.net/lianai911/article/details/42807277