UVa 10382

题目

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1323


题意

长方形l * w,给出长方形中间那条线上n个圆的圆心c和半径r,选取最少数目的圆覆盖长方形,选不了输出-1

思路

明显,算出圆在边上的坐标,然后尽量从左向右扩展就行

感想:

卡题的原因是反射性以为r和w很小,但其实可以很大,所以用double存r

代码

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#define LOCAL_DEBUG
using namespace std;
typedef pair<double, double> MyPair;
const int MAXN = 1e4 + 4;
double c[MAXN];
double r[MAXN];
MyPair myRange[MAXN];
double posmx[MAXN];

int main() {
#ifdef LOCAL_DEBUG
    freopen("C:\Users\Iris\source\repos\ACM\ACM\input.txt", "r", stdin);
    //freopen("C:\Users\Iris\source\repos\ACM\ACM\output.txt", "w", stdout);
#endif // LOCAL_DEBUG
    int T;
    int n, l, w;
    for (int ti = 1;cin>>n>>l>>w; ti++) {
        for (int i = 0; i < n; i++) {
            cin >> c[i] >> r[i];
            double gap = (r[i] >= (w / 2.0) ? sqrt(r[i] * r[i] - w * w / 4.0) : -1);
            myRange[i] = MyPair(c[i] - gap, c[i] + gap);
        }
        sort(myRange, myRange + n);
        bool fl = myRange[0].first <= 0;
        double pos = 0;
        int ans = 0;
        for (int i = 0; i < n && fl && pos < l; ans++) {
            double posNxt = -1;
            while (i < n && myRange[i].first <= pos) {
                posNxt = max(posNxt, myRange[i].second);
                i++;
            }
            if (posNxt <= pos && pos < l) { fl = false; }
            else pos = posNxt;
        }
        if (!fl || pos < l)ans = -1;
        printf("%d
", ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xuesu/p/10463325.html