杭电1006

网上转载的,感谢大神

先给给思路:
正解应该是:
这个钟是个物理的钟,也就是说秒针每一秒走6度之后,分针就走了10分之1度,然后时针又走了120分之1度,当然钟表盘一圈是360度了~或者还可以继续拆,秒针每千分之一秒走千分之6度,然后分针就走万分之1度,时针就走十二万分之1度,就这样……

只要知道他是一个连续的钟,那就什么都好解决了
首先我们有一个东西是必然可以知道的,在0点的时候三根针是重合的,然后在12点的时候三跟针就又重合了(操,我最开始的时候居然想的是24的时候三根针才再次重复),也就是说一天被分为两个周期,每个周期12个小时。所以,只要我们求出在一个周期中三根针满足条件的总时间,我们就可以知道一天中三根针满足条件的总时间。所占百分比也自然就出来了……

好了,这东西肯定不能暴力,如果你按一秒为梯度来暴力解出每一秒的时候三根针之间的间距,然后把总时间求和,精度肯定不够,甚至可能是错误的解,当然,如果你以万分之一秒为梯度来暴力求解的话,那有可能就达到题目的精度了,但是,多半也就超时了

所以,就只有解方程了……

好,最开始我想的是用三个方程,分别表示三根针随时间的变化的角度的变化,就是说第0秒秒针的角度是0度,第1秒是6度,第30秒是180度,第59秒时60-6度……
然后把两跟针的度数相减,就得到了他们之间相距的角度……不过,我发现这个好麻烦……而且整个方程和给定的角度D完全没有关系,也很难根据那个D来解出我们想要的结果……

所以,换了,将方程改为随时间变化的针之间相距的角度的方程,也是三个。
首先,我们知道每根针的角速度:
Vs = 6度每秒 (60秒走一圈360度 360/60=6)
Vm = 1/10度每秒(3600秒,一个小时走一圈, 360/3600=0.1)
Vh = 1/120度每秒(12小时走一圈,360/(3600*12)= 1/120)

然后,就可以得到每两根之间的速度差了:
Vsm = Vs - Vm = 6 - 1/10 = 59/10
Vsh = Vs - Vh = 6 - 1/120 = 719/120
Vmh = Vm - Vh = 1/10 - 1/120 = 11/120

然后,时间乘以速度等于距离。
然后我们可以算出来:
秒针和分针之间的夹角在时间t = 0的时候是0度,在t = 1800/59(59分之1800秒)的时候达到最大值180度,然后从59分之1800秒开始就开始减少,当时间t到达59分之3600秒的时候,秒针和分针之间的夹角就又是0度了。(算法:Vsm * t = 180 ,所以 t = 180/Vsm = 180 /(59/10) = (180 * 10)/ 59
时针和秒的0度-180度-0度这三个点的时间t分别是 0, 120*180/719, 120*180*2/719
时针和分针:0, 180*120/11, 180*120*2/11
所以:
Dsm = (59/10) * t   或者  360 - (59/10) * t  
Dsh = (719/120) * t 或者  360 - (719/120) * t
Dmh = (11/120) * t  或者  360 - (11/120) * t

这里t是时间,D就是两根针之间的距离了……sm就是秒针和分针之间的距离,sh就是秒针和时针之间的距离,mh当然就是分针和时针之间的距离了呗……sm

#include <cstdio> 
#include <iostream> 
using namespace std; 

inline double max(double a,double b,double c) 

a= a > b ? a: b; 
a= a > c ? a: c; 
return a; 

inline double min(double a,double b,double c) 

a= a < b ? a: b; 
a= a < c ? a: c; 
return a; 

int main() 

double hdans; 
double dsm[1444],dsh[1444],dmh[26]; 
//dsm存放秒针与分针之间的角度,dsh存放秒针与时针之间的角度 
//dmh存放分针与时针之间的角度。 
double s,m,h; 

s=3600.0000/59; 
m=43200.0000/719; 
h=43200.0000/11; 

while(cin >> hdans && hdans !=-1) 

int i,j; 
int sp[2],mp[2],hp[2]; 
double sum=0; 
double x=0,y=0; 
dsm[0] = (10*hdans)/59; 
dsh[0] = (120*hdans)/719; 
dmh[0] = (120*hdans)/11; 

dsm[1] = s-dsm[0]; 
dsh[1] = m-dsh[0]; 
dmh[1] = h-dmh[0]; 

for(i=2,j=3; ;i+=2,j+=2) 

dsm[i] = dsm[i-2]+s; 
dsm[j] = dsm[j-2]+s; 
if(dsm[i]>43200 && dsm[j]>43200) 
break; 

for(i=2,j=3;;i+=2,j+=2) 

dsh[i] = dsh[i-2]+m; 
dsh[j] = dsh[j-2]+m; 
if(i==1436) 
i=1436; 
if(dsh[i]>43200 && dsh[j]>43200) 
break; 

for(i=2,j=3;;i+=2,j+=2) 

dmh[i] = dmh[i-2]+h; 
dmh[j] = dmh[j-2]+h; 
if(dmh[i]>43200 && dmh[j]>43200) 
break; 

//以上代码用来根据hdans初始化dsm,dsh,dmh; 
sp[0]=mp[0]=hp[0]=0; 
sp[1]=mp[1]=hp[1]=1; 
//sp,mp,hp分别为dsm,dsh,dmh的上下界指针。 
while(y<=43200 && x<=43200) 

x=max(dsm[sp[0]],dsh[mp[0]],dmh[hp[0]]); 
y=min(dsm[sp[1]],dsh[mp[1]],dmh[hp[1]]); 
if(x<y) 
sum+=y-x; 

if(y==dsm[sp[1]]) {sp[0]+=2;sp[1]+=2;} 
if(y==dsh[mp[1]]) {mp[0]+=2;mp[1]+=2;} 
if(y==dmh[hp[1]]) {hp[0]+=2;hp[1]+=2;} 

printf("%.3f ",sum/432); 
}//while 
return 0; 
}

原文地址:https://www.cnblogs.com/MarsMercury/p/8149013.html