qwq自闭
第一次见到卡精度卡成这样 细节卡到这样的题
qwq
首先,对于这个题,一个比较容易想到的东西就是二分最后的答案,然后去 ,但是check的时候qwq 我就wei掉了
换一种方法考虑,我们对于每一关的要求,实际上要满足的是找到一组 满足
那么我们把
看成一个常数系数的话,实际上这就转化成了一个直线的半平面交的问题
我们要求两个直线满足
注意直线的方向,应该是相反的两个方向的直线。
但是实际上这个题还是有很多的坑点
1. 要开到
2.抛物线只能开口向下
3.抛物线不能是直线
4.要注意一个点的半平面交,以及要开
反正就是很自闭了
qwq
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
#define ld long double
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 1e6+1e2;
const ld eps = 1e-18;
const ld pai = acos(-1);
const ld inf = 1e15+1;
int dcmp(ld x)
{
if (x>eps) return 1;
if (x<-eps) return -1;
return 0;
}
struct Point
{
ld x,y;
};
Point operator + (Point a,Point b)
{
return (Point){a.x+b.x,a.y+b.y};
}
Point operator - (Point a,Point b)
{
return (Point){a.x-b.x,a.y-b.y};
}
Point operator * (Point a,ld b)
{
return (Point){a.x*b,a.y*b};
}
Point operator / (Point a,ld b)
{
return (Point){a.x/b,a.y/b};
}
struct Line
{
Point x,y;
ld ang;
int num;
};
Line ccount(Point x,Point y,int oo)
{
Point now = y-x;
Line a;
a.x=x;
a.y=y;
a.ang = atan2(now.y,now.x);
a.num = oo;
return a;
}
ld diancheng(Point x,Point y)
{
return x.x*y.x+x.y*y.y;
}
ld chacheng(Point x,Point y)
{
return x.x*y.y-x.y*y.x;
}
bool pingxing(Line a,Line b)
{
return dcmp(chacheng(a.y-a.x,b.y-b.x))==0;
}
bool isright(Line a,Point b)
{
return dcmp(chacheng(a.y-a.x,b-a.x))==-1;
}
Point jiaodian(Line a,Line b)
{
return a.x+(a.y-a.x) * (chacheng(b.y-b.x,a.x-b.x)/chacheng(a.y-a.x,b.y-b.x));
}
bool operator <(Line a,Line b)
{
ld now = a.ang-b.ang;
if (dcmp(now)!=0)
{
if (dcmp(now)==-1) return 1;
else return 0;
}
else
{
ld tmp = chacheng(a.y-a.x,b.y-a.x);
if (dcmp(tmp)==-1) return 1;
else return 0;
}
}
int n,m;
Line l[maxn];
Line qx[maxn];
Point qd[maxn];
int num;
Line ymh[maxn];
bool solve(int n)
{
int head=0,tail=1;
qx[++head]=l[1];
for (int i=2;i<=n;i++)
{
if (dcmp(l[i].ang-l[i-1].ang)==0) continue;
if (head<tail && (pingxing(qx[head],qx[head+1]) || pingxing(qx[tail],qx[tail-1]))) return false;
while (head<tail &&isright(l[i],qd[tail-1])) tail--;
while (head<tail && isright(l[i],qd[head])) head++;
qx[++tail]=l[i];
if (head<tail) qd[tail-1]=jiaodian(qx[tail],qx[tail-1]);
}
while (head<tail && isright(qx[head],qd[tail-1])) tail--;
while (head<tail && isright(qx[tail],qd[head])) head++;
if (tail-head+1<=2) return false;
qd[tail]=jiaodian(qx[head],qx[tail]);
int tmp=0;
for (int i=head;i<=tail;i++) if (qd[i].x<0) tmp++;
if (tmp==0) return false;
return true;
}
bool check(int mid)
{
int num=0;
for (int i=1;i<=n;i++)
{
if (ymh[i].num<=mid) l[++num]=ymh[i];
}
return solve(num);
}
int main()
{
m=read();
for (int i=1;i<=m;i++)
{
long double x,y,z;
scanf("%Lf%Lf%Lf",&x,&y,&z);
Point xx = (Point){0,y/x};
Point yy = (Point){1,y/x-x};
Point xxx = (Point){0,z/x};
Point yyy = (Point){1,z/x-x};
int ii=i;
++n;
ymh[n]=ccount(xx,yy,ii);
ymh[n].num=i;
++n;
ymh[n]=ccount(yyy,xxx,ii);
ymh[n].num=i;
}
Point a = (Point){-inf,eps};
Point b = (Point){inf,eps};
Point c = (Point){inf,inf};
Point d = (Point){-inf,inf};
ymh[++n]=ccount(a,b,0);
ymh[++n]=ccount(b,c,0);
ymh[++n]=ccount(c,d,0);
ymh[++n]=ccount(d,a,0);
sort(ymh+1,ymh+1+n);
int l=0,r=m;
int ans=0;
while(l<=r)
{
int mid = l+r >> 1;
if (check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans;
return 0;
}