NC219736. 场地选择
描述
在实验室门前居住着可爱的小松鼠一家。
今天是小松鼠的成人礼,小松鼠的父亲准备为自己的孩子准备一场宏大的表演晚会。
为了让所有到场的嘉宾都有一个良好的观赏体验,选取一个合适的表演场地是至关重要的。
表演将在小松鼠家的院子举行,在这里有很多排已经放置好的观赏座椅。
现在请你计算出能让每一个观众都看到完整表演舞台的舞台面积的最大值。
我们认为一个位置是可以被某一排观赏座椅上的嘉宾看到的当且仅当这个位置在该排座椅的左侧。
小松鼠家里的院子可以看作是一个大小的正方形。
每一排观赏座椅可以看作端点在正方形边上的有向线段。
在这个样例中,面积最大的表演舞台就是多边形abcdefg,也就是被彩色线条填充的部分,而答案就是这个多边形的面积。
输入描述
第 1 行一个整数 n (0 <= n <= 100) 表示座椅的排数第2 ~ n + 1行四个浮点数 ai,bi,ci,di 表示第 i 排座椅的两个端点分别是(ai,bi)(ci,di)【(ai,bi)是起点,(ci,di)是终点】两个端点必然都在正方形的边上。
输出描述
一个浮点数,表示答案。您的答案将被认为是正确的当且仅当您的答案与答案相对差值小于10-6
示例1
输入:
4 0 3 971 0 781 0 1000 945 392 1000 1000 504 0 313 685 1000
输出:
19310.2
C++ 解法, 执行用时: 4ms, 内存消耗: 548K, 提交时间: 2021-08-25 17:34:38
#include<bits/stdc++.h> using namespace std; typedef long long ll; struct Point{ double x,y; Point(double x=0,double y=0):x(x),y(y) {} }; typedef Point Vector; 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 p) {return Vector(A.x*p,A.y*p);} Vector operator /(Vector A,double p) {return Vector(A.x/p,A.y/p);} bool operator < (const Point& a,const Point& b){ return a.x<b.x||(a.x==b.x&&a.y<b.y); } const double eps=1e-6; int dcmp(double x){ if(fabs(x)<eps) return 0;else return x<0?-1:1; } bool operator == (const Point& a,const Point &b){ return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; } typedef vector<Point> Polygon; 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;} Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){ Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } bool OnSegment(Point p,Point a1,Point a2){ return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0; } Polygon CutPolygon(Polygon poly,Point A,Point B){ Polygon newpoly; int n=poly.size(); for(int i=0;i<n;i++){ Point C=poly[i]; Point D=poly[(i+1)%n]; if(dcmp(Cross(B-A,C-A))>=0) newpoly.push_back(C); if(dcmp(Cross(B-A,C-D))!=0){ Point ip=GetLineIntersection(A,B-A,C,D-C); if(OnSegment(ip,C,D)) newpoly.push_back(ip); } } return newpoly; } double PolygonArea(Polygon p){ int n=p.size(); double area=0; for(int i=1;i<n-1;i++) area+=Cross(p[i]-p[0],p[i+1]-p[0]); return area/2; } int main(){ ios::sync_with_stdio(false); int n;cin>>n; Polygon now; now.push_back(Point(0.0,0.0)); now.push_back(Point(1000.0,0.0)); now.push_back(Point(1000.0,1000.0)); now.push_back(Point(0.0,1000.0)); for(int i=0;i<n;i++){ double a,b,c,d;cin>>a>>b>>c>>d; now=CutPolygon(now,Point(a,b),Point(c,d)); } cout<<fixed<<setprecision(1)<<PolygonArea(now)<<endl; }