码迷,mamicode.com
首页 > 其他好文 > 详细

【贪心】时空定位II 区间覆盖

时间:2016-07-20 21:34:02      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

问题 : 【贪心】时空定位II

题目描述

有一块空间,横向长w,纵向长为h,在它的横向中心线上不同位置处装有n(n≤10000)个点状的定位装置,每个定位装置i定位的效果是让以它为中心半径为Ri的圆都被覆盖。请在给出的定位装置中选择尽量少的定位装置,把整个空间全部覆盖。

输入

第一行输入一个正整数N表示共有n次测试数据。
每一组测试数据的第一行有三个整数n,w,h,n表示共有n个定位装置,w表示空间的横向长度,h表示空间的纵向长度。
随后的n行,都有两个整数xi和ri,xi表示第i个定位装置的横坐标(最左边为0),ri表示该定位装置能覆盖的圆的半径。

输出

每组测试数据输出一个正整数,表示共需要多少个定位装置,每个输出单独占一行。
如果不存在一种能够把整个空间覆盖的方案,请输出0。

样例输入

2
2 8 6
1 1
4 5
2 10 6
4 5
6 5

样例输出

1
2
思路:求出每个区间的左右端点, 然后按左端点排序;
从左到右扫一遍就好。
技术分享
#include <bits/stdc++.h>

using namespace std;
const int maxn = 605;
struct uct {
    double left, right;
};
bool cmp(uct a, uct b) {
    if(a.left == b.left) {
        return a.right > b.right;
    }
    return a.left < b.left;
}

int main() {
    ios::sync_with_stdio(false);
    uct s[maxn];
    int n, t;
    cin >> t;
    while(t--) {
        double r, w, h, x;
        cin >> n >> w >> h;
        h = h*1.0/2;
        for(int i = 0; i < n; i++) {
            cin >> x >> r;
            if(r > h) {
                double y = r*r - h*h;
                s[i].left =  max(x - sqrt(y), 0.0);
                s[i].right = min(x + sqrt(y), w);
            } else {
                s[i].left = x;
                s[i].right = x;
            }
        }
        sort(s, s+n, cmp);
        int cnt = 0;
        double start = 0;
        int i = -1;
        while(start < w && s[i+1].left <= start) {
            double MAX = -1;
            for(int j = i + 1; s[j].left <= start && j < n; j++) {
               if(MAX < s[j].right){
                MAX =  s[j].right;
                i = j;
               }
            }
            start  = MAX;
            cnt++;
        }
        if(start >= w) cout << cnt << endl;
        else cout << 0 << endl;
    }
    return 0;
}
我咋帅得一塌糊涂

 

【贪心】时空定位II 区间覆盖

标签:

原文地址:http://www.cnblogs.com/cshg/p/5689647.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!