YY一下,我们觉得答案一定会过某个线段的某个端点,所以我们枚举这个直线过哪个端点,这样我们如果知道了斜率就能确定直线了,而现在每一条线段都覆盖了一段斜率区间,把线段拆成加入和删除排序扫一下就行了
斜率用y/x算的话不但要特判过Y轴而且还会被卡精度,所以我们用x/y来算就好了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 2010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
struct line{
double x1;
double x2;
double y;
int len;
friend bool operator <(line x,line y){
return x.y>y.y;
}
};
struct evt{
double k;
int v;
friend bool operator <(evt x,evt y){
return fabs(x.k-y.k)>eps?x.k<y.k:x.v>y.v;
}
};
struct pt{
double x;
double y;
pt(){
}
pt(double _x,double _y){
x=_x;
y=_y;
}
};
int n;
line a[MAXN];
evt e[MAXN*2];
int tot;
pt O;
ll ans,now;
double xl(pt x,pt y){
return (x.x-y.x)/(x.y-y.y);
}
void cal(int i){
int j;
tot=0;
for(j=1;a[j].y>a[i].y;j++){
double k1=xl(O,pt(a[j].x1,a[j].y));
double k2=xl(O,pt(a[j].x2,a[j].y));
e[++tot].k=k1;
e[tot].v=a[j].len;
e[++tot].k=k2;
e[tot].v=-a[j].len;
}
for(j=i+1;a[j].y==a[i].y;j++){
}
for(;j<=n;j++){
double k1=xl(O,pt(a[j].x2,a[j].y));
double k2=xl(O,pt(a[j].x1,a[j].y));
e[++tot].k=k1;
e[tot].v=a[j].len;
e[++tot].k=k2;
e[tot].v=-a[j].len;
}
sort(e+1,e+tot+1);
for(i=1;i<=tot;i++){
now+=e[i].v;
ans=max(ans,now);
}
}
int main(){
int i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%lf%lf%lf",&a[i].x1,&a[i].x2,&a[i].y);
if(a[i].x1>a[i].x2){
swap(a[i].x1,a[i].x2);
}
a[i].len=a[i].x2-a[i].x1+eps;
}
sort(a+1,a+n+1);
for(i=1;i<=n;i++){
O=pt(a[i].x1,a[i].y);
now=a[i].len;
ans=max(ans,now);
cal(i);
O=pt(a[i].x2,a[i].y);
now=a[i].len;
ans=max(ans,now);
cal(i);
}
printf("%lld\n",ans);
return 0;
}
/*
3
1 2 1
3 4 1
5 6 1
*/