//这个题真的很坎坷了,由于我自己写的精度不够,精度够了又超时······
//解题思想及代码实现来自http://blog.sina.com.cn/s/blog_69fc13c50100l89a.html
//通过角速度解题
// --1-- 稍加分析,可以发现对时间离散化计数行不通,因为要想达到精度,则必定超时.
// --2-- 既然离散地统计不行,那就改为统计时间段. 试想,指针之间的夹角是关于时、分、秒的线性函数,
// --3-- 如果时、分确定,那么我们就得到关于秒的线性不等式组,其解集必定是一些区间的交或并.
// --4-- 容易从区间的交或并中统计出“快乐时光”的长度. 具体如下:
// --5-- 设当前的时间为 H:M:S, 其中 0 <= H < 12, 0 <= M < 60, 0 <= S < 60, H,M皆为整数, S为实数
// --6-- 于是时针、分针、秒针相对于时刻 0:0:0 的转角分别为
// --7-- A(H) = 30H + M/2 + S/120;
// --8-- A(M) = 6M + S/10;
// --9-- A(S) = 6S;
// --10-- 设题目中的临界夹角为 D,则“快乐时光”是同时满足以下不等式的解:
// --11-- D <= | A(H) - A(M) | <= 360-D; (1) |A(H)-A(M)|=|30H-5.5M-11S/120|=|11S/120-(30H-5.5M)|【即a=30H-5.5M,b=11/120】
// --12-- D <= | A(H) - A(S) | <= 360-D; (2) |A(H)-A(S)|=|30H+0.5M-719S/120|=|719S/120-(30H+0.5M)|【即a=30H+0.5M,b=719/120】
// --13-- D <= | A(M) - A(S) | <= 360-D; (3) 同理计算对应的bS-a中的b,a
// --14-- 上面各式的绝对值中的形式为 bS - a,(a,b为常数,b>0) 故解的形式为
// --15-- [ (a+D)/b, (a+360-D)/b) ] 并 [ (a+D-360)/b, (a-D)/b ], 即两个闭区间的并集.
// --16-- 设由式(i)得到的解集为 Si1 并 Si2, 那么“快乐时光”在时、分确定的情况下,其秒的解集为
// --17-- [0,60] 交 (S11 并 S12) 交 (S21 并 S22) 交 (S31 并 S32)
// --18-- 上面的集合容易化成 S1 并 S2 并 S3 并 S4 并 S5 并 S6 并 S7 并 S8 的形式,其中 S1,S2,...皆为闭区间.
// --19-- 求区间的并的总长度没有困难,而这个总长度就是由时、分确定的“快乐时光”的长度.
#include < stdio.h >
typedef struct SEGMENT //定义闭区间[a,b]结构的SEGMENT结构体,使用typedef定义其别名segment
{
double a; //结构体成员a
double b; //结构体成员b
}Segment;
/*自定义结构体的运算符‘ * ’,其作用为计算闭区间交集,返回类型为segment结构变量
*但是ACM提交时编译报错,所以改为下面函数方式
*
Segment operator *(Segment S1 , Segment S2)
{
Segment seg;
seg.a = S1.a > S2.a ? S1.a : S2.a;
seg.b = S1.b < S2.b ? S1.b : S2.b;
if ( seg.a >= seg.b )
seg.a = seg.b = 0.0;
return seg;
}
*/
//求区间S1与S2交集
Segment Intersection ( Segment S1 , Segment S2)
{
Segment seg;
seg.a = S1.a > S2.a ? S1.a : S2.a;
seg.b = S1.b < S2.b ? S1.b
杭电ACM——1006——Tick and Tick
最新推荐文章于 2021-03-04 10:48:43 发布