1006HDU

	这道题的题目很容易懂,但要独立做出来却很难,下面的代码也是借鉴的网上的方法
	方法的大致思路是这样的:
	1.肯定不可能一秒一秒的算,这样将每一秒看作一点算出来肯定精度是不够的,因为时间是连续的
	2.每一根针与另外两根针都有一个从重合到再重合的时间段,在这个时间段里,两根针肯定会经历一个从相距D角度到相距(360-D)角度的过程。
	3.上午0点到中午12点和中午十二点到凌晨十二点是一样的,又因为题目算的是百分比,所以只需要考虑上午的12个小时即可。
	4.因此,枚举从0点0时0分到12点0时0分的每一段两针从重合到再重合的时间,每确定一个时间段,那么在这个时间段里,两针相差D角度和相差(360-D)角度的时间段也就确定了。然后分别对三根针两两之间进行这样的分析,找到三者都相差D角度的时间段。
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
//totalTime是12个小时的总秒数
//v_s_m表示每一秒钟秒针比分针多走多少度
//v_s_h表示每一秒钟秒针比时针多走多少度
//v_m_h表示每一秒钟分针比时针多走多少度
	double T=360.0,d,totalTime=12.0*3600,v_s_m=59.0/10,v_s_h=719.0/120,v_m_h=11.0/120;
	//t_s_m表示秒针与分针从重合到再重合需要多少秒
	//t_s_h表示秒针与时针从重合到再重合需要多少秒
	//t_m_h表示分针与时针从重合到再重合需要多少秒
	double t_s_m=T/v_s_m,t_s_h=T/v_s_h,t_m_h=T/v_m_h;
	while(cin>>d&&d!=-1) {
	//这里声明的数据表示两根针之间相差d角度需要多少秒
		double degree_s_m=d/v_s_m,degree_s_h=d/v_s_h,degree_m_h=d/v_m_h;
		//这里声明的数据表示两根针之间相差(360-d)角度需要多少秒
		double t_degree_m_h=(T-d)/vm_h,t_degree_s_m=(T-d)/v_s_m,t_degree_s_h=(T-d)/v_s_h;
		double sum=0;
		//开始枚举每一个时间段
		for(double i=0; i<=totalTime; i+=t_m_h) {
			for(double j=0; j<=totalTime; j+=t_s_m) {
			//如果秒针与分针之间刚刚相差d角度的时间已经大于了分针与时针之间相差360-d角度的时间
			//那么可知以后的秒针与分针从重合到再重合的时间段绝对不在分针与时针所在的这个时间段内,下面的几个判断都是类似的思路
			if(j+degree_s_m>i+t_degree_m_h)break;
				if(j+t_degree_s_m<i+degree_m_h)continue;
				for(double k=0; k<=totalTime; k+=t_s_h) {
					if((k+degree_s_h>i+t_degree_m_h)||(k+degree_s_h>j+t_degree_s_m))break;
					if((k+t_degree_s_h<i+degree_m_h)||(k+t_degree_s_h<j+degree_s_m))continue;
					double p=max(max(i+degree_m_h,j+degree_s_m),k+degree_s_h);
					double q=min(min(i+t_degree_m_h,j+t_degree_s_m),k+t_degree_s_h);
					if(q>p)sum+=q-p;
				}
			}
		}
		printf("%.3lf\n",sum/totalTime*100.0);
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值