UVA10382-Watering Grass(贪心)

来源:互联网 发布:java记录日志的方式 编辑:程序博客网 时间:2024/05/18 03:07

题目链接

http://acm.hust.edu.cn/vjudge/problem/21419

题意

给定一个长方形,并且给定一系列圆的圆心p和半径r,要求用最小的圆将长方形覆盖住

思路

区间覆盖问题,关键是怎么转化为区间,因为只需要覆盖住长方形,所以我们可以只考虑长方形和圆相交的部分
这里写图片描述
如图,这样就将圆的覆盖转化成了区间覆盖问题

感觉这题的精度比较神奇,最先加了eps一直WA,后来没有考虑精度竟然直接A掉了,附上两个没加eps和加了eps的AC代码

代码

  1. 无eps
#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PDD pair<double, double>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)#define pr(x) cout << #x << " = " << x << endl#define lc o << 1#define rc o << 1 | 1#define pl() cout << endlconst int maxn = 10000 + 5;const int eps = 1e-6;int n;double l, w;bool cmp(PDD x, PDD y) {    return x.first < y.first;}int main() {    while (~scanf("%d %lf %lf", &n, &l, &w)) {        vector<PDD> v;        v.clear();        double p, r;        for (int i = 0; i < n; i++) {            scanf("%lf %lf", &p, &r);            if (r <= w / 2) continue;            double x = sqrt(sqr(r) - sqr(w) / 4.0);            v.push_back(mp(p - x, p + x));        }        double st = 0.0, ted = 0.0;        int tot = 0;        sort(v.begin(), v.end(), cmp);        int len = v.size();        int i = 0;        while (i < len) {            if (st >= l) break;            if (v[i].first > st && st < l) break;            ted = v[i].second;            while (i < len && v[i].first <= st) {                ted = max(ted, v[i].second);                i++;            }            st = ted;            tot++;        }        if (st >= l) printf("%d\n", tot);        else printf("-1\n");    }    return 0;}
  1. 加上eps
#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PDD pair<double, double>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)#define pr(x) cout << #x << " = " << x << endl#define lc o << 1#define rc o << 1 | 1#define pl() cout << endlconst int maxn = 10000 + 5;const int eps = 1e-6;const int tmp = 0;int n;double l, w;bool cmp(PDD x, PDD y) {    return x.first < y.first;}int main() {    while (~scanf("%d %lf %lf", &n, &l, &w)) {        vector<PDD> v;        v.clear();        double p, r;        for (int i = 0; i < n; i++) {            scanf("%lf %lf", &p, &r);            if (r <= w / 2) continue;            double x = sqrt(sqr(r) - sqr(w) / 4.0);            v.push_back(mp(p - x, p + x));        }        double st = 0.0, ted = 0.0;        int tot = 0;        sort(v.begin(), v.end(), cmp);        int len = v.size();        int i = 0;        while (i < len) {            if (st >= l + eps) break;            if (v[i].first > st + eps && st < l - eps) break;            ted = v[i].second;            while (i < len && v[i].first <= st - eps) {                ted = max(ted, v[i].second);                i++;            }            st = ted;            tot++;        }        if (st >= l + eps) printf("%d\n", tot);        else printf("-1\n");    }    return 0;}
0 0
原创粉丝点击