HDU 6551 Clock【枚举】

wls 有一个钟表,当前钟表指向了某一个时间。
又有一些很重要的时刻,wls 想要在钟表上复现这些时间(并不需要依次复现)。我们可以顺时针转动秒针,也可以逆时针转动秒针,分针和时针都会随着秒针按规则转动,wls 想知道秒针至少转动多少角度可以使每个时刻至少都会被访问一次。
注意,时钟上的一种时针分针秒针的组合,可以代表两个不同的时间。

 

Input

第一行一个整数 n 代表有多少个时刻要访问。
第二行三个整数 h,m,s 分别代表当前时刻的时分秒。
最后n行每一行三个整数 hi,mi,si 代表每个要访问的时刻的时分秒。
1 ≤ n ≤ 86, 400
0 ≤ h, hi < 24
0 ≤ m, mi, s, si < 60

 

Output

输出一行一个数代表秒钟转的角度,答案保留两位小数。

思路:总共也就四种情况吧,顺时针,逆时针,先顺后逆,先逆后顺,我们只需要枚举终点就行了,需要注意的是时钟只能表示12个小时。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
struct node
{
    int x, d1, d2; //位置,顺时针距离和逆时针距离
    bool operator < (const node &r) const
    {
        return d1 < r.d1;
    }
}a[maxn];

int main()
{
    int n;
    scanf("%d", &n);
    int h, m, s;
    scanf("%d%d%d", &h, &m, &s);
    if(h >= 12)
        h -= 12;
    int start = h * 3600 + m * 60 + s;
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d%d%d", &h, &m, &s);
        if(h >= 12)
            h -= 12;
        a[i].x = h * 3600 + m * 60 + s;
    }
    int T = 12 * 60 * 60;
    //计算距离
    for(int i = 1; i <= n; ++i)
    {
        if(a[i].x >= start)
        {
            a[i].d1 = a[i].x - start;
            a[i].d2 = T - a[i].d1;
        }
        else
        {
            a[i].d2 = start - a[i].x;
            a[i].d1 = T - a[i].d2;
        }
    }
    sort(a + 1, a + n + 1);
    int ans = 1e9;
    //先顺后逆
    for(int i = 1; i <= n; ++i)
    {
        if(i == n)
            ans = min(ans, a[i].d1); //顺时针
        else
            ans = min(ans, 2 * a[i].d1 + a[i + 1].d2);
    }
    //先逆后顺
    for(int i = n; i > 0; --i)
    {
        if(i == 1)
            ans = min(ans, a[i].d2); //逆时针
        else
            ans = min(ans, 2 * a[i].d2 + a[i - 1].d1);
    }
    double p = ans * 6.0;
    printf("%.2f\n", p);

    return 0;
}

 

你可能感兴趣的:(水题,HDU)