luogu題解 UVA1615 【Highway】
阿新 • • 發佈:2018-05-25
min LG https sizeof 左右 pac stream 不難 題目
- 題目鏈接:
https://www.luogu.org/problemnew/show/UVA1615
- 分析:
首先這裏的距離是歐幾裏得距離而不是曼哈頓距離。
然後我們對於每個點,求出在公路上保持D範圍內最遠的兩個端點,這兩個端點構成一個區間,我們要做的就是選出盡量少的點使所有區間至少有一個點,就是典型的區間選點問題。
怎麽做呢?把所有區間右端點從小到大排序,如果右端點相同左端點小的在前面。
達到貪心的目的,我們設一個pos=-inf,然後遍歷所有區間,如果pos>該區間左端點,cnt+1,pos=區間右端點,然後結合之前的排序方式就不難理解。
註意:
可能有些人不知道怎麽求左右端點,這要用到一點解析幾何知識,每個點\((a,b)\)
有多組數據
代碼:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cctype> #include <cmath> using namespace std; const int maxn=1000005; struct Seg{ double l,r; bool operator <(const Seg &b)const{ if(r==b.r)return l>b.l; return r<b.r; } }seg[maxn]; double l,d; int n; int main(){ while(scanf("%lf %lf %d",&l,&d,&n)!=EOF){ int cnt=0; for(register int i=1;i<=n;i++){ double x,y; scanf("%lf %lf",&x,&y); double sqr=sqrt(d*d-y*y); seg[i].l=max(0.0,-sqr+x); seg[i].r=min(l,sqr+x); } sort(seg+1,seg+1+n); double pos=-19260817.0; for(register int i=1;i<=n;i++){ if(seg[i].l>pos){ pos=seg[i].r; cnt++; } } printf("%d\n",cnt); memset(seg,0,sizeof(seg)); } return 0; }
luogu題解 UVA1615 【Highway】