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 }

 

posted @ 2017-03-02 21:28  ws_ccd  阅读(221)  评论(0编辑  收藏  举报