題意:就是找鐘錶的三個指針兩兩之間的角度超過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);
}
}