每日一题 day35 打卡
Analysis
先将不符合条件的区间去掉(即半径小于W,不然宽度无法符合),将符合条件的按区间存入节点中。区间的左边界是x-sqrt(r*r-W*W/4.0),要计算x轴的最小长度,而不是x-r。然后将区间按照左边界从小到大排序,依次找到能够覆盖L点的最大右端点。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define int long long 7 #define maxn 15000+10 8 #define rep(i,s,e) for(register int i=s;i<=e;++i) 9 using namespace std; 10 inline int read() 11 { 12 int x=0; 13 bool f=1; 14 char c=getchar(); 15 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 16 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 17 if(f) return x; 18 return 0-x; 19 } 20 inline void write(int x) 21 { 22 if(x<0){putchar('-');x=-x;} 23 if(x>9)write(x/10); 24 putchar(x%10+'0'); 25 } 26 int T,n,L,W,num,ans; 27 struct node 28 { 29 double x,y; 30 }reg[maxn]; 31 bool cmp(node x,node y) 32 { 33 return x.x<y.x; 34 } 35 signed main() 36 { 37 T=read(); 38 while(T--) 39 { 40 num=0; 41 memset(reg,0,sizeof(reg)); 42 n=read();L=read();W=read(); 43 rep(i,1,n) 44 { 45 int x=read(),r=read(); 46 if(r<=W/2) continue; 47 reg[++num].x=x-sqrt((double)r*r-(double)W*W/4.0); 48 reg[num].y=x+sqrt((double)r*r-(double)W*W/4.0); 49 } 50 sort(reg+1,reg+num+1,cmp); 51 int cnt=1,ans=0; 52 double now=0; 53 while(now<L) 54 { 55 ++ans; 56 double re=now; 57 while(reg[cnt].x<=re&&cnt<=num) 58 { 59 if(now<reg[cnt].y) now=reg[cnt].y; 60 ++cnt; 61 } 62 if(re==now&&now<L) 63 { 64 ans=-1; 65 break; 66 } 67 } 68 write(ans); 69 putchar(' '); 70 } 71 return 0; 72 }
请各位大佬斧正(反正我不认识斧正是什么意思)