题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2732
题意:给出n条第一象限内的竖直线段。求一个最大的K,使得某条经过原点的抛物线穿过前K条线段。
思路:设线段为(x,y1,y2),设抛物线为y=ax^2+b^x,那么有:y1<=ax^2+bx<=y2。据此可得到穿过该线段的抛物线参数a和b的两个方程,这两个方程是线性的。因此,可以半平面交,直到半平面内的点构不成多边形。
struct point
{
double x,y;
point(){}
point(double _x,double _y)
{
x=_x;
y=_y;
}
point operator+(point a)
{
return point(x+a.x,y+a.y);
}
point operator-(point a)
{
return point(x-a.x,y-a.y);
}
double operator*(point a)
{
return x*a.y-y*a.x;
}
point operator*(double t)
{
return point(x*t,y*t);
}
point operator/(double t)
{
return point(x/t,y/t);
}
};
point a[2][N];
int n,cnt[2],pre,cur;
int sgn(double x)
{
if(x>EPS) return 1;
if(x<-EPS) return -1;
return 0;
}
int getDir(point p,point q,point a)
{
double t=(q-p)*(a-p);
return sgn(t)>=0;
}
void add(point p)
{
a[cur][cnt[cur]++]=p;
}
point cross(point a,point b,point p,point q)
{
double s1=(a-p)*(b-p);
double s2=(b-q)*(a-q);
double t=s1+s2;
return (p*s2+q*s1)/(s1+s2);
}
void cut(double k,double b,int isLeft)
{
point p=point(0,b),q=point(100,100*k+b);
cnt[cur]=0;
int i;
a[pre][cnt[pre]]=a[pre][0];
point p1,q1;
int x,y;
FOR0(i,cnt[pre])
{
p1=a[pre][i];
q1=a[pre][i+1];
x=getDir(p,q,p1)==isLeft;
y=getDir(p,q,q1)==isLeft;
if(x&&y) add(p1);
else if(x) add(p1),add(cross(p,q,p1,q1));
else if(y) add(cross(p,q,p1,q1));
}
}
int main()
{
RD(n);
pre=0,cur=1;
a[pre][0]=point(inf,0);
a[pre][1]=point(inf,inf);
a[pre][2]=point(-inf,inf);
a[pre][3]=point(-inf,0);
cnt[pre]=4;
double x,y1,y2;
int ans,i,flag=0;
FOR1(i,n)
{
RD(x,y1,y2);
if(flag) continue;
ans=i;
cut(-x,y1/x,1); swap(pre,cur);
cut(-x,y2/x,0); swap(pre,cur);
if(cnt[pre]<=2) ans=i-1,flag=1;
}
PR(ans);
}