- 题意: 给出两根木棍,求最多能接到多少水
- 思路: 疯狂判断 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\n",ans+eps); } return 0; }
精度可以调小一点,1e4的数据会有精度误差