地址
题意
- 输入D角度,当时针,分针,秒针两两的角度都大于或等于D时,则三者都很开心,问一天中,三者都开心的时间占了百分之几?
解题思路:
分析
- 我们都知道12个小时为时针分针秒针的一个周期,所以我们只需要计算12小时内的即可。
错误思路:
- 遍历12个小时的每秒钟,然后判断夹角,累计求和。
- 原因:因为精度要求比较高,所以只能求夹角范围。
正确思路:
完整代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
double degree;
struct Interval
{
double left;
double right;
};
Interval Intersection2(Interval A, Interval B)
{
Interval N = {0,0};
if(A.right <= B.left || B.right <= A.left)
return N;
A.left = max(B.left, A.left);
A.right = min(B.right, A.right);
if(A.left>A.right)
return N;
return A;
}
Interval Intersection3(Interval A, Interval B, Interval T)
{
return Intersection2(Intersection2(A, B), T);
}
void Slove(double k, double b, Interval *tmp)
{
Interval A, B, C;
A.left = (degree - b) / k;
A.right = 60;
B.left = 0;
B.right = (-degree - b) / k;
C.left = (degree - 360 - b) / k;
C.right = (360 - degree - b) / k;
Interval T = {0, 60};
tmp[0] = Intersection3(A, C, T);
tmp[1] = Intersection3(B, C, T);
}
double HappyTime(int hh, int mm)
{
Interval result[3][2];
Slove(11.0 / 120, -30.0 * hh + 11.0 / 2 * mm, result[0]);
Slove(719.0 / 120, -30.0 * hh - 1.0 / 2 * mm, result[1]);
Slove(59.0 / 10, -6.0 * mm, result[2]);
double sum = 0;
for(int x = 0; x < 2; x++)
{
for(int y = 0; y < 2; y++)
{
for(int z = 0; z < 2; z++)
{
Interval T = Intersection3(result[0][x], result[1][y], result[2][z]);
sum += T.right - T.left;
}
}
}
return sum;
}
int main()
{
while(scanf("%lf", °ree) && degree >= 0)
{
double happytime = 0;
for(int hh = 0; hh < 12; hh++)
{
for(int mm = 0; mm < 60; mm++)
{
double result = HappyTime(hh, mm);
happytime += result;
}
}
printf("%.3lf\n", happytime * 100 / (12 * 60 * 60));
}
return 0;
}