Tick and Tick HDU - 1006(枚举区间)

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

题意:
时针分针秒针角度相差至少为D占一天的比例是多少

思路:
理解错题的了,以为是一秒一秒的算,然后直接模拟,结果样例都没过。
本题中时钟时间是连续的,发觉事情并不简单,最后参考了别人博客才过。。。

因为时间是连续的,所以直接枚举秒精度是不够的,除非枚举到0.01s,但是这样会T。

本题需要的是枚举合理区间,然后算交集。
算出时针分针角度为D的开始和结束时间,这是第一个区间。算出分针相对时针走360度的时间,那么就可以算出时针分针合理的所有区间,依次类推。
算出时针秒针角度为D的开始和结束时间,这是第二个区间。
算出分针秒针角度为D的开始和结束时间,这是第三个区间。

算出这三个区间的交集就是结果。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;

double VS = 6.0,VM = 1.0 / 10.0,VH = 1 / 120; //时分秒针的速度 °/s
double SH = 719.0 / 120, SM = 59.0 / 10, MH = 11.0 / 120; //相对速度
double TSH = 43200.0 / 719, TSM = 3600.0 / 59, TMH = 43200.0 / 11; //相对转360度所需时间

double MIN(double A,double B,double C) {
    return min(A,min(B,C));
}

double MAX(double A,double B,double C) {
    return max(A,max(B,C));
}

int main() {
    int D;
    while(~scanf("%d",&D) && D != -1) {
        double BSH,BSM,BMH;
        double ESH,ESM,EMH;
        double Begin,End,Sum = 0.0;
        
        //相差角度为D的开始时间
        BSH = (double)D / SH;
        BSM = (double)D / SM;
        BMH = (double)D / MH;
        
        //相差角度为D的结束时间
        ESH = (double)(360 - D) / SH;
        ESM = (double)(360 - D) / SM;
        EMH = (double)(360 - D) / MH;
        
        for(double b1 = BSH,e1 = ESH;e1 <= 43200 + 1e-6;b1 += TSH,e1 += TSH) {
            for(double b2 = BSM,e2 = ESM;e2 <= 43200 + 1e-6;b2 += TSM,e2 += TSM) {
                if(e2 < b1 || e1 < b2) continue;
                for(double b3 = BMH,e3 = EMH;e3 <= 43200 + 1e-6;b3 += TMH,e3 += TMH) {
                    Begin = MAX(b1,b2,b3);
                    End = MIN(e1,e2,e3);
                    if(End >= Begin) {
                        Sum += End - Begin;
                    }
                }
            }
        }
        
        printf("%.3f\n",Sum / 432);
    }
    return 0;
}

枚举秒WA掉的代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <deque>
#include <string>
#include <iostream>
#include <cmath>
using namespace std;

typedef long long ll;

bool check(int h,int m,int s,int D) {
    int num1 = fabs(h - m);
    int num2 = fabs(h - s);
    int num3 = fabs(s - m);
    if(num1 >= 180 * 120) num1 = 360 * 120 - num1;
    if(num2 >= 180 * 120) num2 = 360 * 120 - num2;
    if(num3 >= 180 * 120) num3 = 360 * 120 - num3;
    
    if(num1 < D * 120) return false;
    if(num2 < D * 120) return false;
    if(num3 < D * 120) return false;
    return true;
}

int main() {
    int D;
    while(~scanf("%d",&D) && D != -1) {
        int per_h = 120 * 360 / 43200;
        int per_m = 120 * 360 / 3600;
        int per_s = 120 * 360 / 60;
        
        int h = 0,m = 0,s = 0;
        
        int ans = 0;
        for(int i = 1;i <= 43200;i++) {
            h += per_h;
            m += per_m;
            s += per_s;
            if(h >= 360 * 120) h -= 360 * 120;
            if(m >= 360 * 120) m -= 360 * 120;
            if(s >= 360 * 120) s -= 360 * 120;
            if(check(h,m,s,D)) {
                ans++;
            }
        }
        printf("%.3f\n",(double)2 * ans * 100 / 86400);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/108339760