这道题的题目很容易懂,但要独立做出来却很难,下面的代码也是借鉴的网上的方法
方法的大致思路是这样的:
1.肯定不可能一秒一秒的算,这样将每一秒看作一点算出来肯定精度是不够的,因为时间是连续的
2.每一根针与另外两根针都有一个从重合到再重合的时间段,在这个时间段里,两根针肯定会经历一个从相距D角度到相距(360-D)角度的过程。
3.上午0点到中午12点和中午十二点到凌晨十二点是一样的,又因为题目算的是百分比,所以只需要考虑上午的12个小时即可。
4.因此,枚举从0点0时0分到12点0时0分的每一段两针从重合到再重合的时间,每确定一个时间段,那么在这个时间段里,两针相差D角度和相差(360-D)角度的时间段也就确定了。然后分别对三根针两两之间进行这样的分析,找到三者都相差D角度的时间段。
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
double T=360.0,d,totalTime=12.0*3600,v_s_m=59.0/10,v_s_h=719.0/120,v_m_h=11.0/120;
double t_s_m=T/v_s_m,t_s_h=T/v_s_h,t_m_h=T/v_m_h;
while(cin>>d&&d!=-1) {
double degree_s_m=d/v_s_m,degree_s_h=d/v_s_h,degree_m_h=d/v_m_h;
double t_degree_m_h=(T-d)/vm_h,t_degree_s_m=(T-d)/v_s_m,t_degree_s_h=(T-d)/v_s_h;
double sum=0;
for(double i=0; i<=totalTime; i+=t_m_h) {
for(double j=0; j<=totalTime; j+=t_s_m) {
if(j+degree_s_m>i+t_degree_m_h)break;
if(j+t_degree_s_m<i+degree_m_h)continue;
for(double k=0; k<=totalTime; k+=t_s_h) {
if((k+degree_s_h>i+t_degree_m_h)||(k+degree_s_h>j+t_degree_s_m))break;
if((k+t_degree_s_h<i+degree_m_h)||(k+t_degree_s_h<j+degree_s_m))continue;
double p=max(max(i+degree_m_h,j+degree_s_m),k+degree_s_h);
double q=min(min(i+t_degree_m_h,j+t_degree_s_m),k+t_degree_s_h);
if(q>p)sum+=q-p;
}
}
}
printf("%.3lf\n",sum/totalTime*100.0);
}
return 0;
}