UVa 1615 - Highway

链接:

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

 

题意:

给定平面上n(n≤1e5)个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个点,
都至少有一个选出的点离它的欧几里德距离不超过D(每个给定的点离x轴的距离至多为D)。

 

分析:

区间覆盖问题。每个给定的点在x轴上都有一个选点区间,先令所有给定的点按x坐标升序排列,
则第1,2,3,...,x(1≤x≤n)个给定的点的选点区间的公共部分即为第一个选出的点的范围,以此类推。

 

代码:

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 struct COORDINATE {
 7     int x, y;
 8     bool operator < (const COORDINATE& that) const {
 9         return x < that.x;
10     }
11 } a[1000000];
12 
13 bool legal(double L, double R, double L2, double R2){ //判断[L2,R2]是否与[L,R]有公共部分
14     L = max(L, L2);  R = min(R, R2);
15     return L <= R;
16 }
17 
18 int main(){
19     int len, d, n;
20     while(~scanf("%d%d%d", &len, &d, &n)){
21         for(int i = 0; i < n; i++) scanf("%d%d", &a[i].x, &a[i].y);
22         sort(a, a + n);
23 
24         int ans = 1;
25         double L = 0, R = len;
26         for(int i = 0; i < n; i++){
27             double m = sqrt(d * d - a[i].y * a[i].y);
28             double L2 = a[i].x - m, R2 = a[i].x + m; //求出当前点的选点区间[L2,R2]
29             if(legal(L, R, L2, R2)) L = max(L, L2), R = min(R, R2); //更新公共部分
30             else L = max(0.0, L2), R = min((double)len, R2), ans++;
31         }
32         printf("%d\n", ans);
33     }
34     return 0;
35 }

 

posted @ 2018-02-27 23:18  Ctfes  阅读(197)  评论(0编辑  收藏  举报