题意:就是找钟表的三个指针两两之间的角度超过n的概率。
解题思路:将一天的时间24小时只求12小时即可,因为后12小时和前12小时每种情况出现的概率一样,找出三个指针的相对角度:hm、hs、ms。以及时间t_hm、t_hs、t_ms。我们可以求出从重合到分离n度所需的时间n/hm,n/hs,n/ms,以及到再重合前n度所需的时间(360-n)/hm,(360-n)/hs,(360-n)/ms。每次枚举,i,j,k表示hm,hs,ms各自重合的时间,那么p=max(i+n/hm,j+n/hs,k+ms)就是最早的三针分离n度的时间;q=min(i+(360-n)/hm,j+(360-n)/hs,k+(360-n)/ms)就是最晚三针合并到n度的时间,那么时间区间[p,q]就是符合条件的时间段。
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=12*60*60;
double h,m,s,hm,hs,ms,t_hm,t_hs,t_ms;
void init() {
h=1.0/120;
m=1.0/10;
s=6;
hm=m-h;
hs=s-h;
ms=s-m;
t_hm=360/hm;
t_hs=360/hs;
t_ms=360/ms;
}
int main() {
init();
double n;
while(scanf("%lf",&n)!=EOF) {
if(n<0)break;
double i,j,a[6],k,p,q,ans=0;
a[0]=n/hm;
a[1]=n/hs;
a[2]=n/ms;
a[3]=(360-n)/hm;
a[4]=(360-n)/hs;
a[5]=(360-n)/ms;
for(i=0; i<=1.0*N; i+=t_hm) {
for(j=0; j<=1.0*N; j+=t_hs) {
if(j+a[1]>i+a[3]) break;
if(i+a[0]>j+a[4]) continue;
for(k=0; k<=1.0*N; k+=t_ms) {
if(k+a[2]>i+a[3]||k+a[2]>j+a[4]) break;
if(i+a[0]>k+a[5]||j+a[1]>k+a[5]) continue;
p=max(max(i+a[0],j+a[1]),k+a[2]);
q=min(min(i+a[3],j+a[4]),k+a[5]);
if(q>p)
ans+=q-p;
}
}
}
printf("%.3lf\n",100.0*ans/N);
}
}