问题可以转化为草坪的边界被完全覆盖。这样一个圆形就换成一条线段。
贪心,从中选尽量少的线段把区间覆盖,按照把线段按左端点排序,记录一个当前已经覆盖区间的位置cur,
从左端点小于等于cur选一个右端点最大的作为这次选的区间,如果没有符合条件的,说明不可能完全覆盖。
r*r会爆int...
#include<bits/stdc++.h> using namespace std; const int maxn = 1e4+5; int n,l,w; struct seg { double l,r; bool operator < (const seg& rh)const { return l < rh.l; } }L[maxn]; int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d%d",&n,&l,&w)){ double d = w*w/4.; int ss = 0; for(int i = 0; i < n; i++){ int p,r; scanf("%d%d",&p,&r); if(2*r<=w) { continue; } double dx = sqrt(1.*r*r-d); L[ss].l = p-dx; L[ss++].r = p+dx; } sort(L,L+ss); double cur = 0.; bool fg = false; int ans = 0; for(int i = 0; i < ss;){ int j = i; double nxt = cur; while(j<ss && L[j].l <= cur) { if(L[j].r > nxt) nxt = L[j].r; j++; } if(j == i) break; ans++; cur = nxt; i = j; if(cur>=l){ fg = true; break; } } if(fg) printf("%d\n",ans); else puts("-1"); } return 0; }
时间: 2024-11-03 22:04:38