hdu1006Tick and Tick解题报告

acm小菜鸡的日常更新~~~
The three hands of the clock are rotating every second and meeting each other many times everyday. Finally, they get bored of this and each of them would like to stay away from the other two. A hand is happy if it is at least D degrees from any of the rest. You are to calculate how much time in a day that all the hands are happy.
Input
The input contains many test cases. Each of them has a single line with a real number D between 0 and 120, inclusively. The input is terminated with a D of -1.
Output
For each D, print in a single line the percentage of time in a day that all of the hands are happy, accurate up to 3 decimal places.
Sample Input
0
120
90
-1
Sample Output
100.000
0.000
6.251
题目意思:时针,分针,秒针在分开一定角度之后才会感到开心,
求时针,分针,秒针在一天中开心时间的百分比。
首先十二个小时时针转了一圈,所以十二小时为一个大循环。
在一秒钟内,时针的速度为60/12*60*60=1/120度
分针的速度为60/360=0.1度,秒针的速度为6度每秒。
接下来判断时针,分针,秒针之间的关系:
360*k1+快乐分离时间<=分针速度-时针速度<=360*(k1+1)-快乐分离时间
因为时针十二小时走一圈,分针十二小时走十二圈,所以分针最多超时针十一圈,又因为分针的速度在[0,11)圈之内,时针的圈数在[0,1)圈之内,且分钟的速度比时针的速度快,所以分针超越时针的圈数在[0,10]圈之内,所以k1>=0,k1+1<=11(因为360*(k1+1)-快乐分离时间是超了k1圈,因为减去了一个快乐分离时间,所以还没到k1+1圈)
即k1在[0,10],
同理可得:360*k2+快乐分离时间<=秒针速度-分针速度<=360*(k2+1)-快乐分离时间,k2的范围在[0,707]之间
360*k3+快乐分离时间<=秒针速度-时针速度<=360*(k3+1)-快乐分离时间,k3的范围在[0,718]之间,
设时针速度为1/120t,分针速度为0.1t,秒针速度为6t,根据这三个式子可以得到满足条件的t的个数,进而求得百分比。
对于三个式子化简
(360*k1+快乐分离时间)/(0.1-1/120)<=t<=(360*(k1+1)-快乐分离时间)/(0.1-1/120);
(360*k2+快乐分离时间)/(6-1/120)<=t<=(360*(k2+1)-快乐分离时间)/(6-0.1)
(360*k3+快乐分离时间)/(0.1-1/1200)<=t<=(360*(k3+1)-快乐分离时间)/(6-1/120),k3的范围在[0,718]之间
求同时满足三个等式的条件,也就是求三个区间的交集

#include  <iostream>
#include  <algorithm>
#include  <cstdio>
using  namespace  std;
int  main()
{
    double  a = 1.0/120.0,b=0.1,c=6.0;
    //计算出每一个钟表的相对速度
    double  apart;
    double  totaltime = 0.0;
    const  double  maxn = 9999999999.00;
    double  begins = 0,ends = maxn;
    double  begin1,begin2,begin3;
    double  rear1,rear2,rear3;
    while(scanf("%lf",&apart) && apart!=-1)
    {
        totaltime = 0.0;
        for(double  k1=0; k1<=10; k1++)
        {
        //(360*k1+快乐分离时间)/(0.1-1/120)<=t<=(360*(k1+1)-快乐分离时间)/(0.1-1/120);
            begin1 = (360*k1+apart)/(b-a);
            //求出第一个区间的开始位置
            rear1 = (360*k1+360-apart)/(b-a);
            //求出第一个区间的结束位置
            for(double  k2=0; k2<=707; k2++)
            {
                begin2 = (360*k2+apart)/(c-b);
                rear2 = (360*k2+360-apart)/(c-b);
                //(360*k2+快乐分离时间)/(6-1/120)<=t<=(360*(k2+1)-快乐分离时间)/(6-0.1)
                double  o1 = max(begin1,begin2);
                double  f1 = min(rear1,rear2);
                //求三个区间的交集即求出第一个区间,第二个区间,第三个区间的开头位置的最小值以及结束位置的最大值,就能求出三个区间的交集的开头位置和结束位置
                if(f1 <= o1)
                {
                    continue;
                }//优化时间,如果第一个区间与第二个区间没有交集就没有必要进行第三个循环
                for(double  k3=0; k3<=718; k3++)
                {
                    begin3 = (360*k3+apart)/(c-a);
                    rear3 = (360*k3+360-apart)/(c-a);
                //(360*k3+快乐分离时间)/(0.1-1/1200)<=t<=(360*(k3+1)-快乐分离时间)/(6-1/120)
                    double o2 = max(o1,begin3);
                    double f2 = min(f1,rear3);
                    //求三个区间的交集
                    if(o2<f2)
                    {
                    //o2为交集的结束位置,f2为交集的开始位置
                    //两个位置的差值就是满足条件的时间
                        totaltime +=f2 - o2;
                    }
                }
            }
        }
        printf("%.3f\n",(double)totaltime/(12*6*6));
    }
    return  0;
}
发布了17 篇原创文章 · 获赞 7 · 访问量 3002

猜你喜欢

转载自blog.csdn.net/znevegiveup1/article/details/81488305