HDU-1006Tick and Tick

题意:就是找钟表的三个指针两两之间的角度超过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);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39564498/article/details/81584338