[HDU]1006 Tick and Tick

这是HDU,Online Judge上的一道题,http://acm.hdu.edu.cn/showproblem.php?pid=1006闲来没事,研究的做做,开始思路是模拟每一秒,然后计算满足条件占所有时间的比例,最后发现计算结果不够准确,然后采用了找交集的思路,先用相对角速度,求出两两之间多长时间后会出现一次夹角循环,然后找出在12小时内他们相互满足条件的交集。我这里给出的参考也是参考了晒代码网上的参考答案。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
#define CIRCLE 43200.000001
//三个指针的相对角速度
const double s_h = 719. / 120, s_m = 59. / 10, m_h = 11. /120;
//将角速度换为周期,即两指针多长时间后出现一次夹角循环,43200秒即12小时,12小时三个指针重合一次
const double tsh = 43200. / 719, tsm = 3600. / 59, tmh = 43200. / 11;
inline double max(double a, double b, double c)
{
	double max = a;
	if(b > max)
		max = b;
	if(c > max)
		max = c;
	return max;
}
inline double min(double a, double b, double c)
{
	double min = a;
	if(b < min)
		min = b;
	if(c < min)
		min = c;
	return min;
}
int main(int argc, const char *argv[]){
	double d;
	while(scanf("%lf", &d), d != -1){
		double bsm, bsh, bmh, esm, esh, emh, begin, end, total = 0;
		//两两之间第一次满足条件的时间
		bsm = d / s_m;
		bsh = d / s_h;
		bmh = d / m_h;
		//两两之间第一次满足条件结束的时间
		esm = (360 - d) / s_m;
		esh = (360 - d) / s_h;
		emh = (360 - d) / m_h;
		//通过循环找出,三者之间共同的交集,
		// |____|    |____|    |____|     |____|
		//   |____|    |____|    |____|    |____|
		//     |____|    |____|     |____|     |____|
		//因为CIRCLE为一个周期,所以满足范围必定不会跨越CIRCLE,所以et3 <= CIRCLE合理
		for(double bt3 = bsh, et3 = esh; et3 <= CIRCLE; bt3 += tsh, et3 += tsh){
			for(double bt2 = bmh, et2 = emh; et2 < CIRCLE; bt2 += tmh, et2 += tmh){
				if(et2 < bt3)	//        et2  |______|	//et2还需要增长
					continue;	//	|______|  	bt3	
				if(bt2 > et3)	//  |______|    bt2
					break;		//        et3	 |______|	//bt2再增长也不会有交集了,break
				for(double bt1 = bsm, et1 = esm; et2 <= CIRCLE; bt1 += tsm, et1 += tsm){
					if(et1 < bt3 || et1 < bt2)
						continue;
					if(bt1 > et3 || bt1 > et2)
						break;
					begin = max(bt1, bt2, bt3);
					end = min(et1, et2, et3);
					total += (end - begin);
				}
			}
		}
		printf("%.3lf\n", total / 432);
	}
	return 0;
}


你可能感兴趣的:(ACM)