HDU 1006 Tick and Tick

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22812319/article/details/81637987

题目概括

输入:0~120之间的实数变量D,当D为-1时退出

输出:钟表上三个指针两两相距大于等于D的时间占整天时间的百分比

Sample Input

0 120 90 -1

Sample Output

100.000 0.000 6.251

分析

这个问题需要选定时间单位,采用枚举法搜索,善用区间去除不可能情况,缩短时间消耗。参考 这里 的思路,代码也是仿写的。
首先,计算三者的角速度(°/s),这里以 秒 为单位。

秒针: 6 °/s

分钟:1/10 °/s

时针:1/120 °/s

那么,两两之间的角速度差可以定义为:

秒针和分针 sm = 11/120 °/s

秒针和时针 sh = 719/120 °/s

分针和时针 mh = 11/120 °/s

所以,两两之间每相隔1°,需要的时间为:

秒针和分针 t_sm = 120/11 s

秒针和时针 t_sh = 120/719 s

分针和时针 t_mh = 120/11 s

计算出首次满足角度D的时间和首次不满足角度D的时间,求三者的交集,分别取最大值和最小值,就是满足的时间。

/*****************************************************************
*Name:tick and tick
*Time:20180813-seaf1re
参考:https://blog.csdn.net/lianai911/article/details/42807277
由于三者会在12小时后再次相遇,选定12小时区间计算即可。
*****************************************************************/

#include <iostream>
#include <stdio.h>
#include <algorithm>
const double sm = 59.0/10,sh = 719.0/120,mh = 11.0/120; //必须显式写成.0的格式,否则会存为整数
const double t_sm = 360*10.0/59,t_sh = 360*120.0/719,t_mh = 360*120.0/11; //走1°的时间 * 360 = 走一圈的时间

using namespace std;

//定义最大值最小值函数
double Min(double a,double b,double c){
    return min(c,min(a,b));
}
double Max(double a,double b,double c){
    return max(c,max(a,b));
}

int main()
{
    double D;

    while(cin >> D && D != -1){
        double b_sm,b_sh,b_mh,e_sm,e_sh,e_mh,start,finish,sum = 0;
        if(D == 0){ //计算边界情况
            sum = 100;
            printf("%.3lf\n",100.0);
            continue;
        }

        //第一次满足条件的时间
        b_sm = D / sm;
        b_sh = D / sh;
        b_mh = D / mh;
        //第一次不满足条件的时间
        e_sm = (360 - D) / sm;
        e_sh = (360 - D) / sh;
        e_mh = (360 - D) / mh;
        //寻找可能的时间,求三种情况的交集.顺序可交换
         for (double b1 = b_sm,e1 = e_sm; e1 <= 12 * 60 * 60; b1 += t_sm , e1 += t_sm){
            for (double b2 = b_sh,e2 = e_sh; e2 <= 12 * 60 * 60; b2 += t_sh , e2 += t_sh){
                if(e2 < b1) continue;
                if(b2 > e1) break;
                for (double b3 = b_mh,e3 = e_mh; e3 <= 12 * 60 * 60; b3 += t_mh , e3 += t_mh){
                    if(e3 < b2 || e3 < b1) continue;
                    if(b3 > e1 || b3 > e2) break;
                    start = Max(b1,b2,b3);
                    finish = Min(e1,e2,e3);
                    sum += (finish - start);
                }
            }
        }
        printf("%.3lf\n",sum/(12*60*60)*100);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_22812319/article/details/81637987