题意:给一个1*1的正方形,然后每条边上有n个点,按照一定规律连线把矩形切成(n+1)^2个小四边形(方式不好描述,直接看题吧),求这里面面积最大的小四边形。

题解:求四边形面积可以直接用叉积公式,然后用两个扫描线,记录相邻的两条线上组成四边形的所有的点,计算之后,靠右的扫描线变成新的扫描线组的左边的线。

View Code
 1 #include<cstdlib>
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define max(a,b) (((a)>(b))?(a):(b))
 6 #define min(a,b) (((a)>(b))?(b):(a))
 7 #define sign(x) ((x)>eps?1:((x)<-eps?(-1):(0))) //符号函数
 8 using namespace std;
 9 const int MAXN=1000;
10 const double eps=1e-8,inf=1e50;
11 struct point
12 {
13     double x,y;
14     point(){}
15     point(double _x,double _y){x=_x;y=_y;}
16 };
17 struct line
18 {
19     point a,b;
20     line(){}
21     line(point _a,point _b){a=_a;b=_b;}
22 };
23 inline double xmult(point o,point a,point b)
24 {
25     return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
26 }
27 inline double xmult(double x1,double y1,double x2,double y2)
28 {
29     return x1*y2-x2*y1;
30 }
31 inline double dmult(point o,point a,point b)
32 {
33     return (a.x-o.x)*(b.x-o.x)+(a.y-o.y)*(b.y-o.y);
34 }
35 point line_intersection(line u,line v)
36 {
37     double a1=u.b.y-u.a.y,b1=u.a.x-u.b.x;
38     double c1=u.b.y*(-b1)-u.b.x*a1;
39     double a2=v.b.y-v.a.y,b2=v.a.x-v.b.x;
40     double c2=v.b.y*(-b2)-v.b.x*a2;
41     double D=xmult(a1,b1,a2,b2);
42     return point(xmult(b1,c1,b2,c2)/D,xmult(c1,a1,c2,a2)/D);
43 }
44 inline double getarea(point pg[],int n)
45 {
46     double area=0;
47     pg[n]=pg[0];
48     for(int i=0;i<n;i++)
49         area+=xmult(pg[i].x,pg[i].y,pg[i+1].x,pg[i+1].y);
50     return fabs(area)/2.0;
51 }
52 line li[2][50];
53 point po[2][50],res[4][50];
54 int main()
55 {
56     int n;
57     while(scanf("%d",&n)!=EOF&&n)
58     {
59         double ans=0;
60         for(int i=0;i<n;i++)
61             scanf("%lf",&res[0][i].x),res[0][i].y=0.0;
62         for(int i=0;i<n;i++)
63             scanf("%lf",&res[1][i].x),res[1][i].y=1.0,li[0][i]=line(res[0][i],res[1][i]);
64         for(int i=0;i<n;i++)
65             scanf("%lf",&res[2][i].y),res[2][i].x=0.0,po[0][i+1]=res[2][i];
66         for(int i=0;i<n;i++)
67             scanf("%lf",&res[3][i].y),res[3][i].x=1.0,li[1][i]=line(res[2][i],res[3][i]);
68         po[0][0]=point(0.0,0.0);
69         po[0][n+1]=point(0.0,1.0);
70         for(int i=0;i<n;i++)
71         {
72             int a=i&1,b=a^1;
73             for(int j=0;j<n;j++)
74                 po[b][j+1]=line_intersection(li[1][j],li[0][i]);
75             po[b][0]=res[0][i];
76             po[b][n+1]=res[1][i];
77             for(int j=0;j<=n;j++)
78             {
79                 point temp[6]={po[a][j],po[a][j+1],po[b][j+1],po[b][j]};
80                 ans=max(ans,getarea(temp,4));
81             }
82         }
83         int a=n&1,b=a^1;
84         for(int j=0;j<n;j++)
85             po[b][j+1]=res[3][j];
86         po[b][0]=point(1.0,0.0);
87         po[b][n+1]=point(1.0,1.0);
88         for(int j=0;j<=n;j++)
89         {
90             point temp[4]={po[a][j],po[a][j+1],po[b][j+1],po[b][j]};
91             ans=max(ans,getarea(temp,4));
92         }
93         printf("%.6lf\n",ans);
94     }
95     return 0;
96 }