http://poj.org/problem?id=1408

题意是给定一个1*1的方格,然后每个边有n个点,然后连线求交织出来的四边的最大面积。

首先利用叉积求出所有的交点,(注意边界点单独处理),然后循环遍历所有的四边形求面积。取最大即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 33
using namespace std;
const double eps = 1e-8;
double a[maxn],b[maxn],c[maxn],d[maxn];
struct point
{
    double x,y;
    point(double a = 0,double b = 0): x(a),y(b){}
}p[maxn][maxn];
int n;

int dblcmp(double x)
{
    if (x > eps) return 1;
    else if (x < -eps) return -1;
    else return 0;
}
double det(double x1,double y1,double x2,double y2)
{
    return x1*y2 - x2*y1;
}
double cross(point ta,point tb,point tc)
{
    return det(tb.x - ta.x,tb.y - ta.y,tc.x - ta.x, tc.y - ta.y);
}
//叉积求交点
point segcross(point xa, point xb, point xc, point xd)
{
    double s1, s2;
    int d1, d2, d3, d4;
    point po(0,0);
    d1 = dblcmp(s1 = cross(xa, xb, xc));
    d2 = dblcmp(s2 = cross(xa, xb, xd));
    d3 = dblcmp(cross(xc, xd, xa));
    d4 = dblcmp(cross(xc, xd, xb));
    po.x = (xc.x*s2 - xd.x*s1)/(s2 - s1);
    po.y = (xc.y*s2 - xd.y*s1)/(s2 - s1);
    return po;
}
//叉积求多边形面积
double getsum(point ta,point tb,point tc,point td)
{
    double s = 0;
    s += det(ta.x,ta.y,tb.x,tb.y);
    s += det(tb.x,tb.y,tc.x,tc.y);
    s += det(tc.x,tc.y,td.x,td.y);
    s += det(td.x,td.y,ta.x,ta.y);
    return s*0.5;
}
int main()
{
    int i,j;
   while (~scanf("%d",&n))
   {
       if (!n) break;
       for (i = 1; i <= n; ++i) scanf("%lf",&a[i]);
       for (i = 1; i <= n; ++i) scanf("%lf",&b[i]);
       for (i = 1; i <= n; ++i) scanf("%lf",&c[i]);
       for (i = 1; i <= n; ++i) scanf("%lf",&d[i]);
       //左右两个边界处理一下
       for (j = 0; j <= n + 1; ++j)
       {
           if (j == 0)
           {
               p[0][j].x = p[0][j].y = 0;
               p[n + 1][j].x = 1;
               p[n + 1][j].y = 0;
           }
           else if (j == n + 1)
           {
               p[0][j].x = 0;
               p[0][j].y = 1;
               p[n + 1][j].x = p[n + 1][j].y = 1;
           }
           else
           {
               p[0][j].x = 0;
               p[0][j].y = c[j];
               p[n + 1][j].x = 1;
               p[n + 1][j].y = d[j];
           }
       }
       //上下两个边界处理一下
       for (i = 1; i <= n; ++i)
       {
          p[i][0].x = a[i];
          p[i][0].y = 0;
          p[i][n + 1].x = b[i];
          p[i][n + 1].y = 1;
       }
       //循环求交点
       for (i = 1; i <= n; ++i)
       {
           for (j = 1; j <= n; ++j)
           {
               point xa(a[i],0);
               point xb(b[i],1);
               point xc(0,c[j]);
               point xd(1,d[j]);
               p[i][j] = segcross(xa,xb,xc,xd);
           }
       }
      /* for (i = 0; i <= n + 1; ++i)
       {
           for (j = 0; j <= n + 1; ++j)
           {
               printf("%d %d %.3lf %.3lf\n",i,j,p[i][j].x,p[i][j].y);
           }
       }*/
       //循环遍历四边形求面积
       double ans = -99999999.0;
       for (i = 1; i <= n + 1; ++i)
       {
           for (j = 1; j <= n + 1; ++j)
           {
               double sum = getsum(p[i][j - 1],p[i][j],p[i - 1][j],p[i - 1][j - 1]);
               if (dblcmp(sum - ans) > 0) ans = sum;
           }
       }
      printf("%.6lf\n",ans);
   }
    return 0;
}