[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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章