题目大意:有两块木板交叉起来接雨水,问最多能接多少。
分析:题目描述很简单,不过有些细节还是需要注意到,如下图几种情况:
#include#include #include #include using namespace std;const int MAXN = 107;const double oo = 1e4+7;const double EPS = 1e-8;int sign(double val){ if(val > EPS)return 1; if(fabs(val) < EPS)return 0; return -1;}struct Point{ double x, y; Point(double x=0, double y=0):x(x), y(y){} Point operator - (const Point &tmp) const{ return Point(x-tmp.x, y-tmp.y); } double operator ^(const Point &tmp) const{ return x*tmp.y - y*tmp.x; } bool operator == (const Point &tmp) const{ return fabs(x-tmp.x) < EPS && fabs(y-tmp.y) < EPS; } double operator *(const Point &tmp) const{ return x*tmp.x + y*tmp.y; }};struct Segment{ Point s, e; double a, b, c;///ax + by = c Segment(Point s=0, Point e=0):s(s), e(e){ a = s.y - e.y; b = e.x - s.x; c = e.x*s.y - s.x*e.y; } bool Inter(const Segment &t)const{ int v1 = sign((s-e)^(t.s-e)); int v2 = sign((s-e)^(t.e-e)); if(!v1 && !v2)return false;///共线 if(!v1 && t.s.x >= min(s.x, e.x) && t.s.x <= max(s.x, e.x) && t.s.y >= min(s.y, e.y) && t.s.y <= max(s.y, e.y) || !v2 && t.e.x >= min(s.x, e.x) && t.e.x <= max(s.x, e.x) && t.e.y >= min(s.y, e.y) && t.e.y <= max(s.y, e.y) || v1 * v2 == -1)return true; return false; } Point CrossNode(const Segment &t) const{ Point ans; ans.x = (c*t.b-t.c*b)/(a*t.b-t.a*b); ans.y = (c*t.a-t.c*a)/(b*t.a-t.b*a); return ans; }};double Dist(Point a, Point b){ return sqrt((a-b) * (a-b));}double Find(Point crs, Point p[], int N){ double sum = 0; for(int i=0; i =min(p[i].x, p[j].x) && crs.x<=max(p[i].x, p[j].x) || crs.x>=p[i].x && crs.x>=p[j].x && (k>0&&(p[i].x-p[j].x>EPS) || k<0&&(p[j].x-p[i].x>EPS)) || crs.x<=p[i].x && crs.x<=p[j].x && (k<0&&(p[j].x-p[i].x>EPS) || k>0&&(p[i].x-p[j].x>EPS))) if(p[i].y-crs.y > EPS && p[j].y-crs.y > EPS) { Point A = p[i].y < p[j].y ? p[i] : p[j]; Point B = (A == p[i] ? p[j] : p[i]); Segment t1(Point(-oo, A.y), Point(oo, A.y)); Segment t2(crs, B); B = t1.CrossNode(t2); double La = Dist(A, B); double Lb = Dist(A, crs); double Lc = Dist(B, crs); double p = (La+Lb+Lc) / 2; sum += sqrt(p*(p-La)*(p-Lb)*(p-Lc)); } } return sum;}int main(){ int T; scanf("%d", &T); while(T--) { Point p[MAXN], crs; scanf("%lf%lf%lf%lf", &p[0].x, &p[0].y, &p[1].x, &p[1].y); scanf("%lf%lf%lf%lf", &p[2].x, &p[2].y, &p[3].x, &p[3].y); Segment L1(p[0], p[1]), L2(p[2], p[3]); double ans = 0; if(L1.Inter(L2) && L2.Inter(L1)) { crs = L1.CrossNode(L2); ans = Find(crs, p, 4); } printf("%.2f\n", ans+EPS); } return 0;}