[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();
}
}
总结
二份答案可以解决这类最小化最大问题
考场上一定要冷静, 认真分析才是最重要的