【問題描述】
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;
}