hdu 1006 Tick and Tick(枚举)

传送门

题意:求一天当中有百分之多少时间满足时针、分针、秒针两两所成角度不小于n度(所成角度不大于180度)

题解:第一次写直接将时间离散化处理,跑完样例才发现这样只能求得近似解(比如当n=90时答案始终有误差),因为每一段满足条件的时间段的起始时间和终止时间都不一定是1秒的整数倍。所以考虑两两时针在一次重合和下一次重合这个周期内有多少时间段满足所成角度不小于n度,用三重循环(三根针两两组合有三种组合)枚举这些时间段,计算被三种时间段都覆盖一次的子段,每次答案加上这样的子段的终止时间与起始时间之差即可。这样的枚举的精度远比离散枚举1,2,3.....秒更高。

P.S.在循环时需要剪枝(有些三元组明显无法覆盖同一段时间的可以直接跳过),否则答案能算对但会TLE

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double N=12*60*60;
//speed
const double ss=6.0;
const double sm=0.1;
const double sh=0.1/12;
//relative speed
const double rsm=ss-sm;
const double rsh=ss-sh;
const double rmh=sm-sh;
//relative period of 360
const double tsm=360.0/rsm;
const double tsh=360.0/rsh;
const double tmh=360.0/rmh;
double D;
inline double Abs(double x) {
	return x>0?x:-x;
}
int main() {
//	freopen("in.txt","r",stdin);
	while (scanf("%lf",&D)&&(D!=-1)) {
		double tot=0;
		//relative period of D
		double dsm=D/rsm;
		double dsh=D/rsh;
		double dmh=D/rmh;
		//relative period of 360-D
		double csm=(360.0-D)/rsm;
		double csh=(360.0-D)/rsh;
		double cmh=(360.0-D)/rmh;
		for (double i=0;i<N;i+=tsh)
			for (double j=0;j<N;j+=tsm) {
				if (i+csh<j+dsm) break;
				if (j+csm<i+dsh) continue;
				for (double k=0;k<N;k+=tmh) {
					if (j+csm<k+dmh) break;
					if (k+cmh<j+dsm) continue;
					double a=max(max(i+dsh,j+dsm),k+dmh);
					double b=min(min(i+csh,j+csm),k+cmh);
					if (a<b) tot+=b-a;
				}
			}
		printf("%.3lf\n",tot*100/N);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值