- 题意: 给出两根木棍,求最多能接到多少水
- 思路: 疯狂判断 1. 判断两个线段是否平行 2. 判断是否有交点 3. 求交点和较短木棍的点 4. 判断斜率大的直线会不会覆盖斜率小的直线
求(dis(e,d)>dis(c,d))即可
#include<string>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
#define FOR(i,l,r) for(int i = l ; i <= r ;++i )
using namespace std;
const int maxn = 101;
const double eps = 1e-6;
int sgn(double k){
if(fabs(k)<eps) return 0;
if(k>0) return 1;
return -1;
}
struct point{
double x,y;
point(){}
point(double _x,double _y):x(_x),y(_y){}
void input(){
scanf("%lf%lf",&x,&y);
}
point operator - (point b){
return point(x-b.x,y-b.y);
}
};
struct line{
point a,b;
line(){}
line(point a,point b):a(a),b(b){}
};
double det(point a,point b){
return a.x * b.y - b.x * a.y;
}
bool segcorseg(line l1,line l2){
return sgn(det(l1.a-l2.a,l1.b-l2.a))*sgn(det(l1.a-l2.b,l1.b-l2.b))<=0
&& sgn(det(l2.a-l1.a,l2.b-l1.a))*sgn(det(l2.a-l1.b,l2.b-l1.b))<=0;
}
point crosspoint(line l1,line l2){
double a1 = det(l2.b-l2.a,l1.a-l2.a);
double a2 = det(l2.b-l2.a,l1.b-l2.a);
return point((l1.a.x*a2-l1.b.x*a1)/(a2-a1),(l1.a.y*a2-l1.b.y*a1)/(a2-a1));
}
bool parallel(line l1,line l2){
return sgn(det(l1.b-l1.a,l2.b-l2.a))==0;
}
bool pointonline(point a,line l){
return sgn(det(l.a-a,l.b-a))==0;
}
double dist(point a,point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool check(line l1,line l2){
double x1 = (l1.a.y - l1.b.y)/(l1.a.x-l1.b.x);
double x2 = (l2.a.y - l2.b.y)/(l2.a.x-l2.b.x);
if(sgn(x1)==sgn(x2)){
if(fabs(x1)>fabs(x2)){
point a= crosspoint(l2,line(l1.b,point(l1.b.x,0)));
if(sgn(dist(a,l2.a)-dist(l2.a,l2.b))>=0)
return 0;
}else{
point a= crosspoint(l1,line(l2.b,point(l2.b.x,0)));
if(sgn(dist(a,l1.a)-dist(l1.a,l1.b))>=0)
return 0;
}
}
return 1;
}
int n;
int main(){
int t;
scanf("%d",&t);
while(t--){
point a,b;
double ans = 0.0;
line l1,l2;
a.input(); b.input();
if(a.y>b.y) swap(a,b);
l1 = line(a,b);
a.input(); b.input();
if(a.y>b.y) swap(a,b);
l2 = line(a,b);
if(!parallel(l1,l2) && segcorseg(l1,l2)){
a = crosspoint(l1,l2);
if(pointonline(a,l1) && pointonline(a,l2)){
double y1 = max(l1.a.y,l1.b.y);
y1 = min(y1,max(l2.a.y,l2.b.y));
line l3 = line(point(0,y1),point(10000,y1));
if(!parallel(l1,l3) && !parallel(l2,l3)){
if(check(l1,l2)){
point c = crosspoint(l1,l3);
point d = crosspoint(l2,l3);
ans = fabs(c.x-d.x)*fabs(y1-a.y)*0.5;
}
}
}
}
printf("%.2lf
",ans+eps);
}
return 0;
}
精度可以调小一点,1e4的数据会有精度误差