高速公路(freeway)

【问题描述】

  BOB是一名优秀的工程设计师,他正在设计一条穿越的农村地区的高速公路。为了方便一些村庄的人安全而快捷穿越高速路,需要设计跨越高速公路的人行天桥。当然为了节约成本,BOB须尽量减少天桥的数量。

  在BOB的设计图纸上,高速公路是一条长为L的线段,它的左端点是平面座标系的原点,右端点是x轴正方向的某个点。所有村庄在座标系中标记成点。

  现在请你帮助BOB确定需要修建人行天桥的最少数量,满足每个村庄与最近的天桥的曼哈顿距离不超过D。

【输入格式】

  第1行是一个整数L(1<=L<=10^9),表示高速公路的长度。
  第2行是一个整数D(1<=D<=10^9),表示村庄离自己最近的天桥的距离不超过D。
  第3行是一个整数n(n<=10^5),表示村庄数目。
  接下来的n行,每行包含两个整数x,y,表示村庄的位置座标(0<=x<=L,y属于[-D,D] 且y!=0)。

【输出格式】

  一个整数,表示修建人行天桥的最小数量。

【输入样例】

15
5
5
0 1
2 4
6 3
8 2
13 2

【输出样例】

3

【数据范围】

30%的数据满足:n<=10
70%的数据满足:n<=10,000
100%的数据满足:n<=100,000

题目大意:给你平面座标系2、4象限内某些点的座标,要求在x轴正半轴上选择若干个点,使得这些2、4象限内点到这些点的曼哈顿距离不超过D。求选取最少的点数。

最后一天考试第一题,之前有做过原题,不过当时的做法基本想不起来了,考试的时候画了下图想了想,由于是曼哈顿距离不超过D,所以说将点投影到x轴上后,x轴上平移的距离不能超过D-|y|。这个限制条件使得这个村庄可以修建的天桥应该位于[x-(D-|y|),x+(D-|y|)]内。(如图)
这里写图片描述
所以问题转化为,在x轴上给定n个区间,求在x轴上取最少的点,使得每一个区间都要有一个点。
贪心。
先把所有区间按照右端点从小到大排序,每次选择一个区间时,都把这个点放到区间的右端点,然后更新last,如果和下一个区间有交点就跳过。并记录选择的区间数量,直到考虑完n个区间为止。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100010;
int L,D,n;
struct data
{
    int a,b;
}c[maxn];

bool cmp(data a,data b)//排序
{
    return a.b<b.b;
}

int main()
{
    //freopen("freeway.in","r",stdin);
    //freopen("freeway.out","w",stdout);

    scanf("%d%d%d",&L,&D,&n);
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        c[i].a=x-D+abs(y);//左端点 
        c[i].b=x+D-abs(y);//右端点
    }

    sort(c+1,c+n+1,cmp);

    int i=1,cnt=0;
    while(i<=n)
    {
        int last=c[i].b;//last始终指向当前考虑的区间的右端点
        while(last>=c[i+1].a && i<n)
        {
            i++;
        }
        cnt++;
        i++;
    }
    printf("%d\n",cnt);

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章