Loading

[HDU6807] Fake Photo

思路

考虑二分答案, 那么对于每个时针分针都会生成一个合法指针区间, 我们对时针和分针的限制区间分别取交集

如果时针范围大于 \(1 h\) , 那么分针显然可以走到任何地方
否则分针还会生成一个限制范围, 我们再取交集即可

实现

讲真这比大模拟恶心多了, 真不想写, 以后拿来练马力

写了一个 \(10 + 20 \rm{pts}\)

#include <bits/stdc++.h>
#define int long long

int read() {
    int x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}

int n;
double Max, Min, ans;

double DegAbs(double x) { return (x < 0) ? x + 360 : x; }

class Subtask_1
{
private:

public:
    void solve()
    {
        int h1 = read(), m1 = read(), s1 = read();
        h1 = (h1 >= 12) ? h1 - 12 : h1;
        double H1Deg = 30.0 * h1 + 0.5 * m1, M1Deg = 6.0 * m1;
        int h2 = read(), m2 = read(), s2 = read();
        h2 = (h2 >= 12) ? h2 - 12 : h2;
        double H2Deg = 30.0 * h2 + 0.5 * m2, M2Deg = 6.0 * m2;
        double A1 = DegAbs(H1Deg - H2Deg), B1 = DegAbs(M1Deg - M2Deg);
        double A2 = DegAbs(H2Deg - H1Deg), B2 = DegAbs(M2Deg - M1Deg);
        printf("%.5f", std::min(std::max(A1 / 2, B1 / 2), std::max(A2 / 2, B2 / 2)));
    }
} S_1;

class Subtask_2
{
private:

public:
    void solve()
    {
        Min = 0x3f3f3f3f;
        for (int i = 1; i <= n; i++)
        {
            int h = read(), m = read(), s = read();
            Max = std::max(Max, 6.0 * m + s * 0.1);
            Min = std::min(Min, 6.0 * m + s * 0.1);
        }
        printf("%.5f", (Max - Min) / 2.0);
    }
} S_2;

signed main()
{
    n = read();
    if (n == 2) {
        S_1.solve();
    }
    else
    {
        S_2.solve();
    }
}

总结

二份答案可以解决这类最小化最大问题

考场上一定要冷静, 认真分析才是最重要的

posted @ 2024-12-17 16:20  Yorg  阅读(11)  评论(0)    收藏  举报