HDU-1006 平面几何+区间枚举

题意:找到时针、分针、秒针两两间隔大于D度的时间占一天时间的比例

分析:在0点三者重合,12点又重合,两者是一模一样的所以找12个小时即可。需要算出两个指针的相对角速度,算出相对重合时间,分离D度的时间和满足分离超过D度的时间(为了枚举区间端点),找出公共交集的时间和占总时间的比例即可。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
#include<vector>
using namespace std;
//一天早上12个小时和晚上12个小时是一样的,取一半的时间即可
const double N = 12.0 * 60.0 * 60.0;
int main()
{
    int D;
    double r_hm,r_hs,r_ms,t_hm1,t_hs1,t_ms1,t_hm2,t_hs2,t_ms2,t_hs,t_hm,t_ms;
    while(~scanf("%d",&D) && D != -1)
    {
        //时针、分针、秒针的角速度
        double w_h = 1.0 / 120.0,w_m = 1.0 / 10.0,w_s = 6.0;
        //两针的相对角速度
        r_hm = w_m - w_h;
        r_hs = w_s - w_h;
        r_ms = w_s - w_m;
        //两针的重合时间
        t_hs = 360.0 / r_hs;
        t_hm = 360.0 / r_hm;
        t_ms = 360.0 / r_ms;
        //分离成D度所需要的时间
        t_hm1 = (double)D / r_hm;
        t_hs1 = (double)D / r_hs;
        t_ms1 = (double)D / r_ms;
        //满足大于等于D度的时间
        t_hm2 = (360.0 - (double)D) / r_hm;
        t_hs2 = (360.0 - (double)D) / r_hs;
        t_ms2 = (360.0 - (double)D) / r_ms;
        double res1,res2,ans = 0.0;
        for(double hs = 0.0; hs <= N; hs += t_hs)
            for(double hm = 0.0; hm <= N; hm += t_hm)
        {
            //判断相交,hs相当于一个恒定的区间,左端点小于hm的右端点,右端点大于hm的左端点
            if(hs + t_hs1 > hm + t_hm2)continue;
            if(hs + t_hs2 < hm + t_hm1)break;
            for(double ms = 0.0; ms <= N; ms += t_ms)
            {
                //判断hs和ms,hm和ms是否相交
                if(hs + t_hs2 < ms + t_ms1 || hm + t_hm2 < ms + t_ms1)break;
                if(hs + t_hs1 > ms + t_ms2 || hm + t_hm1 > ms + t_ms2)continue;
                   res1 = min(hs + t_hs2,min(ms + t_ms2,hm + t_hm2));//右端点取最小值,左端点取最大值,公共交集
                   res2 = max(hs + t_hs1,max(ms + t_ms1,hm + t_hm1));
                   if(res2 < res1)//满足右端点大于左端点才可以
                   ans += res1 - res2;
            }
        }
        printf("%.3f\n",ans * 100.0 / N);//求百分率
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值