bzoj 2732: [HNOI2012]射箭
额,,一看就设抛物线是y=a*x^2+b*x,把x,y1,y2带进去就是关于a,b的不等式。。然后半平面交。。。
考虑答案,可以二分。
(然而还是不对,,被卡精度了23333,(话说百度卡常数,,直接连膝盖都没了。。),,而且开始的时候异常自信,直接没加边界,就搞搞搞23333,闷声做大死2333)
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define LL long long 4 #define eps 1e-8 5 #define double long double 6 using namespace std; 7 inline int ra() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 11 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 12 return x*f; 13 } 14 int n,cnt,tot; 15 const double linf=1e15; 16 struct in_data{double x,y1,y2;} q[N]; 17 struct point{double x,y;}; 18 struct line{ 19 point a,b; double angle; 20 void print() 21 { 22 printf("%.1lf %.1lf %.1lf %.1lf\n",a.x,a.y,b.x,b.y); 23 } 24 } l[N<<1],s[N<<1]; 25 double operator * (point a, point b){ 26 return a.x*b.y-a.y*b.x; 27 } 28 point operator - (point a, point b){ 29 point t; t.x=a.x-b.x; t.y=a.y-b.y; return t; 30 } 31 bool operator < (line a, line b){ 32 if (a.angle==b.angle) return (b.b-a.a)*(a.b-a.a)>0; 33 return a.angle<b.angle; 34 } 35 point intersection(line a, line b) 36 { 37 double k1,k2,t; point ans; 38 k1=(b.a-a.a)*(a.b-a.a); 39 k2=(a.b-a.a)*(b.b-a.a); 40 t=k1/(k1+k2); 41 ans.x=b.a.x+(b.b.x-b.a.x)*t; 42 ans.y=b.a.y+(b.b.y-b.a.y)*t; 43 return ans; 44 } 45 bool jud(line a, line b, line t){ 46 point p=intersection(a,b); 47 return (t.a-p)*(t.b-p)<0; 48 } 49 bool half_plane_intersection() 50 { 51 tot=0; 52 for (int i=1; i<=cnt; i++) 53 if (l[i].angle!=l[i-1].angle) l[++tot]=l[i]; 54 int start=1,end=0; cnt=tot; 55 s[++end]=l[1]; s[++end]=l[2]; 56 for (int i=3; i<=cnt; i++) 57 { 58 while (start<end && jud(s[end],s[end-1],l[i])) end--; 59 while (start<end && jud(s[start],s[start+1],l[i])) start++; 60 s[++end]=l[i]; 61 } 62 while (start<end && jud(s[end],s[end-1],s[start])) end--; 63 while (start<end && jud(s[start],s[start+1],s[end])) start++; 64 return end-start>=2; 65 } 66 bool check(int len) 67 { 68 cnt=0; 69 if (len<=2) return 1; 70 for (int i=1; i<=len; i++) 71 { 72 l[++cnt].a.x=-1; l[cnt].a.y=q[i].y1/q[i].x+q[i].x; 73 l[cnt].b.x=1; l[cnt].b.y=q[i].y1/q[i].x-q[i].x; 74 l[++cnt].a.x=1; l[cnt].a.y=q[i].y2/q[i].x-q[i].x; 75 l[cnt].b.x=-1; l[cnt].b.y=q[i].y2/q[i].x+q[i].x; 76 } 77 l[++cnt].a=(point){-linf,-linf};l[cnt].b=(point){linf,-linf}; 78 l[++cnt].a=(point){linf,-linf};l[cnt].b=(point){linf,linf}; 79 l[++cnt].a=(point){linf,linf};l[cnt].b=(point){-linf,linf}; 80 l[++cnt].a=(point){-linf,linf};l[cnt].b=(point){-linf,-linf}; 81 for (int i=1; i<=cnt; i++) 82 l[i].angle=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x); 83 sort(l+1,l+cnt+1); 84 return half_plane_intersection(); 85 } 86 int main() 87 { 88 n=ra(); 89 for (int i=1; i<=n; i++) q[i].x=ra(),q[i].y1=ra(),q[i].y2=ra(); 90 int L=1,R=n,ans; 91 while (L<=R) 92 { 93 int mid=L+R>>1; 94 if (check(mid)) ans=mid,L=mid+1; 95 else R=mid-1; 96 } 97 cout<<ans; 98 return 0; 99 }