描述
题解
不得不说,长时间没有戴我的机械表,对表针的运行都显得十分模棱两可,看智能手表看多了的锅~~~
每次遇见表盘问题总是要墨迹很久,总把问题想得十分复杂,实际上就是基础物理题,不过需要通过计算机暴力枚举。看了大牛们的代码,先求出相对角速度和相对周期……慢,让我想想角速度咋求,呵呵呵,我是真的忘了怎么求了,百度了一下才想起这些高中的物理知识,哎,退化了。
求出来相对角速度和周期后,求各个指针之间第一次满足条件的区间,然后暴力枚举区间(通过周期枚举)求交集也就可以了。
代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const double MAXT = 43200.000001; // 12小时
// const double w_h = 1. / 120, w_m = 1. / 10, w_s = 6.0; // 角速度
// 三根指针间的相对角速度
const double s_h = 719. / 120;
const double s_m = 59. / 10;
const double m_h = 11. / 120;
// 将相对角速度变成周期。(即两针间需要多久出现夹角的循环)
// 同样可求得三个周期的最小公倍数为43200秒,即12小时
const double tsh = 43200. / 719;
const double tsm = 3600. / 59;
const double 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()
{
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; // = tsm - bsm
esh = (360 - D) / s_h; // = tsh - bsh
emh = (360 - D) / m_h; // = tmh - bmh
// 三重循环找出所有的时间总和,当然这三重循环的顺序是可以打乱的
for (double bt3 = bsh, et3 = esh; et3 <= MAXT; bt3 += tsh, et3 += tsh)
{
for (double bt2 = bmh, et2 = emh; et2 <= MAXT; bt2 += tmh, et2 += tmh)
{
if (et2 < bt3) // 这是为了提前判断是否有交集
{
continue;
}
if (bt2 > et3)
{
break;
}
for (double bt1 = bsm, et1 = esm; et1 <= MAXT; bt1 += tsm, et1 += tsm)
{
if (et1 < bt2 || et1 < bt3) // 和上述同理
{
continue;
}
if (bt1 > et2 || bt1 > et3)
{
break;
}
begin = MAX(bt1, bt2, bt3); // 取它们的交集
end = MIN(et1, et2, et3);
total += (end - begin);
}
}
}
printf("%.3lf\n", total / 432);
}
return 0;
}