这是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; }