Problem Description
The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
Input
The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
Output
For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
Sample Input
0 120 90 -1
Sample Output
100.000 0.000 6.251
Author
PAN, Minghao
Source
Recommend
JGShining
解题思路:
秒针的运行速度为:59/10°/s,分针的运行速度为:1/10°/s,时针的运行速度为:1/120°/s;
秒针与分针的速度差v.sm=59/10°/s,秒针与时针的速度差v.sh=719/120,分针与时针的速度差v.mh=11/120;
秒针、分针相遇的周期t.sm=360/v.sm,秒针、时针相遇的周期t.sh=360/v.sh,分针、时针相遇的周期t.mh=360/v.mh;
使秒针、分针相差大于等于d°的时间段为:d / v.sm + k1 * t.sm <= t <= ( 360 - d ) / v.sm + k1 * t.sm; (1)
使秒针、时针相差大于等于d°的时间段为: d / v.sh + k2 * t.sh <= t <= ( 360 - d ) / v.sh + k2 * t.sh; (2)
使分针、时针相差大于等于d°的时间段为:d / v.mh + k3 * t.mh <= t <= ( 360 - d ) / v.mh + k3 * t.mh; (3)
使条件(1)(2)(3)均满足的时间长度占总的时间长度的百分比即为题目所求。
(我选取的总的时间段为零点到十二点之间的时间长度,即43200秒。)
注意:
1.由于这道题目要求的精度很高,所以模拟钟表指针每秒的跳动并不能得出正确的结果。
2.需要避免不需要的计算步骤,否则,必然会Time Limit Exceeded。
程序代码:
#include<stdio.h>
double max(double a , double b , double c )
{
double z ;
z = a ;
if ( z < b )
z = b ;
if ( z < c )
z = c ;
return z ;
}
double min ( double a ,double b , double c )
{
double z ;
z = a ;
if ( z > b )
z = b ;
if ( z > c )
z = c ;
return z ;
}
int main ( )
{
double d , record , start , end ;
int k1 , k2 , k3 ;
while ( scanf("%lf",&d)==1&&d>=0 )
{
record = 0 ;
for ( k1=0 ; k1<11 ; k1++ )
for( k2=(int)((43200/11.0*k1+d/(1/10.0-1/120.0)-d/(6-1/10.0))*59/3600) ; k2<708 ; k2++ )
{
if((3600.0/59*k2+d/(6-1/10.0))>(43200/11.0*(k1+1)-d/(1/10.0-1/120.0)))
break;
for ( k3=(int)((3600.0/59*k2+d/(6-1/10.0)-d/(6-1/120.0))*719/43200) ; k3<719 ; k3++)
{
if((43200.0/719*k3+d/(6-1/120.0))>(3600.0/59*(k2+1)-d/(6-1/10.0)))
break;
start=max(43200.0/719*k3+d/(6-1/120.0),3600.0/59*k2+d/(6-1/10.0),43200/11.0*k1+d/(1/10.0-1/120.0));
end=min(43200.0/719*(k3+1)-d/(6-1/120.0),3600.0/59*(k2+1)-d/(6-1/10.0),43200/11.0*(k1+1)-d/(1/10.0-1/120.0));
if(start<end)
record+=end-start;
}
}
printf("%.3f\n",record*100/43200);
}
return 0;
}