高速公路(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章