POJ 2826 An Easy Problem?![线段]
An Easy Problem?!
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 12970 | Accepted: 1995 |
Description
It's raining outside. Farmer Johnson's bull Ben wants some rain to water his flowers. Ben nails two wooden boards on the wall of his barn. Shown in the pictures below, the two boards on the wall just look like two segments on the plane, as they have the same width.
Your mission is to calculate how much rain these two boards can collect.
Your mission is to calculate how much rain these two boards can collect.
Input
The first line contains the number of test cases.
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1, y1, x2, y2, x3, y3, x4, y4. (x1, y1), (x2, y2) are the endpoints of one board, and (x3, y3), (x4, y4) are the endpoints of the other one.
Each test case consists of 8 integers not exceeding 10,000 by absolute value, x1, y1, x2, y2, x3, y3, x4, y4. (x1, y1), (x2, y2) are the endpoints of one board, and (x3, y3), (x4, y4) are the endpoints of the other one.
Output
For each test case output a single line containing a real number with precision up to two decimal places - the amount of rain collected.
Sample Input
2 0 1 1 0 1 0 2 1 0 1 2 1 1 0 1 2
Sample Output
1.00 0.00
Source
POJ Monthly--2006.04.28, Dagger@PKU_RPWT
哈哈哈A掉了 过年啦!!!
[2017-01-28]
好了好了大年初一补题解:
本题就是特殊情况特别多,参考kuangbin
线段不相交,结果为0.
有一条线段平行于x轴结果也为0;
我最后求面积的方法和别人不太一样,我是从三角形上面两个点中低的做水平线,与另一条交点再用叉积
还有就是好多人说最后答案要加上eps避免-0.00,然而我不加也可以
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <vector> using namespace std; typedef long long ll; const double eps=1e-8; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } inline int sgn(double x){ if(abs(x)<eps) return 0; else return x<0?-1:1; } struct Vector{ double x,y; Vector(double a=0,double b=0):x(a),y(b){} bool operator <(const Vector &a)const{ return x<a.x||(x==a.x&&y<a.y); } void print(){ printf("%lf %lf\n",x,y); } }; typedef Vector Point; Vector operator +(Vector a,Vector b){return Vector(a.x+b.x,a.y+b.y);} Vector operator -(Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);} Vector operator *(Vector a,double b){return Vector(a.x*b,a.y*b);} Vector operator /(Vector a,double b){return Vector(a.x/b,a.y/b);} bool operator ==(Vector a,Vector b){return sgn(a.x-b.x)==0&&sgn(a.y-b.y)==0;} double Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } double Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } double DisPP(Point a,Point b){ Point t=a-b; return sqrt(t.x*t.x+t.y*t.y); } double Len(Vector a){return sqrt(Dot(a,a));} struct Line{ Point s,t; Line(){} Line(Point p,Point v):s(p),t(v){} }; bool isLSI(Line l1,Line l2){ Vector v=l1.t-l1.s,u=l2.s-l1.s,w=l2.t-l1.s; return sgn(Cross(v,u))!=sgn(Cross(v,w)); } bool isSSI(Line l1,Line l2){ return isLSI(l1,l2)&&isLSI(l2,l1); } Point LI(Line a,Line b){ Vector v=a.s-b.s,v1=a.t-a.s,v2=b.t-b.s; double t=Cross(v2,v)/Cross(v1,v2); return a.s+v1*t; } double DisTL(Point p,Point a,Point b){ Vector v1=b-a,v2=p-a; return abs(Cross(v1,v2)/Len(v1)); } int n; double x,y,x2,y2; Line l1,l2; double solve(){ if(sgn(l1.s.y-l1.t.y)==0||sgn(l2.s.y-l2.t.y)==0) return 0; if(sgn(Cross(l1.t-l1.s,l2.t-l2.s))==0) return 0; if(!isSSI(l1,l2)) return 0; if(l1.s.y>l1.t.y) swap(l1.s,l1.t); if(l2.s.y>l2.t.y) swap(l2.s,l2.t); if(isSSI(Line(l1.t,Point(l1.t.x,10000)),l2)) return 0; if(isSSI(Line(l2.t,Point(l2.t.x,10000)),l1)) return 0; //puts("hi"); Point p=LI(l1,l2),a=l1.t,b=l2.t;//p.print(); if(a.y>b.y) swap(a,b),swap(l1,l2); Line t(a,Point(10000,a.y)); Point c=LI(t,l2);//c.print(); return abs(Cross(a-p,c-p))/2; } int main(int argc, const char * argv[]) { int T=read(); while(T--){ scanf("%lf%lf%lf%lf",&x,&y,&x2,&y2); l1=Line(Point(x,y),Point(x2,y2)); scanf("%lf%lf%lf%lf",&x,&y,&x2,&y2); l2=Line(Point(x,y),Point(x2,y2)); printf("%.2f\n",solve()+eps); } return 0; }
Copyright:http://www.cnblogs.com/candy99/