http://acm.hdu.edu.cn/showproblem.php?pid=1006
这题坑了我好久,发现居然是一个除法变成了整除,TAT,所以建议在写较长的运算表达式的时候出现了除法尽量加个强制转换,避免写出了错误的代码检查很久还检查不出来。枚举当前所在的小时数h和分钟数m,设分钟数为s时满足三个针之间的夹角大于等于D,则可得到三跟针的所在位置(偏转的角度),然后列出方程min(d1 - d2, 360 - (d1 - d2)) >= d, min(d1 - d3, 360 - (d1 - d3)) >= d, min(d3 - d2, 360 - (d3 - d2)) >= d。可得出s的解集, s0, s1, ..., s5。则最后的答案是(s0 V s1) ^ (s2 V s3) ^ (s4 V s5)的区间长度, 这里有个技巧,注意s0,s1(其它类似)是不相交的,所以可以合并为一类,一共3类,从每一类中选1个共8种情况,可以证明这8种情况的解集互不相交,故可以单独统计。详见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <stack>
#include <string>
#include <ctime>
#include <queue>
#define mem0(a) memset(a, 0, sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define eps 0.0000001
#define lowbit(x) ((x) & -(x))
#define memc(a, b) memcpy(a, b, sizeof(b))
#define xx(a) ((a) * (a))
using namespace std;
#define LL __int64
#define DB double
#define pi 3.14159265359
#define MD 10000007
#define INF (int)1e9
struct S {
double l, r;
S (double l = , double r = ): l(l), r(r) {}
};
S jiaoS(S s1, S s2)
{
return S(max(s1.l, s2.l), min(s1.r, s2.r));
}
double calc(S a[])
{
double res = ;
for(int i = ; i < ; i++) {
int x1 = i & , x2 = ((i & ) > ) + , x3 = ((i & ) > ) + ;
S ans = jiaoS(a[x1], jiaoS(a[x2], a[x3]));
res += max(0.0, min(60.0, ans.r) - max(0.0, ans.l));
}
return res;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int dd;
while(cin>> dd, dd != -) {
double d = (double)dd;
double ans = ;
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++) {
int h = i, m = j;
S a[] = {
S(10.0 * ( * m + d - ) / , 10.0 * ( * m - d) / ),
S(10.0 * ( * m + d) / , 10.0 * ( * m + - d) / ),
S(120.0 * ( * h + m / 2.0 + d - ) / , 120.0 * ( * h + m / 2.0 - d) / ),
S(120.0 * ( * h + m / 2.0 + d) / , 120.0 * ( * h + m / 2.0 + - d) / ),
S(120.0 * ( * h - 11.0 * m / + d - ) / , 120.0 * ( * h - 11.0 * m / - d) / ),
S(120.0 * ( * h - 11.0 * m / + d) / , 120.0 * ( * h - 11.0 * m / + - d) / )
};
ans += calc(a);
}
}
printf("%.3f\n", ans * / ( * * ));
}
return ;
}