poj 1408(计算几何)


题目大意:

有一个1*1的正方形,分别给出下,上,左,右边每个边上的n个点,对边对应点连线,问这些线段相交的最大的四边形面积是多少(面积最大的定义是必须当前面积内没有更小的四边形内含)。


解题思路:

1、我们可以用一个矩阵来保存所有的点,四边上每个点是输入的,内部的每个点通过线段交点的计算可以计算出来。

2、然后枚举任意i-1,i,j-1,j四个点计算四边形的面积,求最大值。在计算四边形面积的时候四边形可以转换成两个三角形来计算,这两个三角形的面积是通过向量的叉积来计算的。两个向量的叉积可以算出以这两个向量为邻边的四边形的面积,注意除以2.

#include <stdio.h>
#include <math.h>
struct node
{
    double x,y;
} point[35][35];
double max(double a, double b)
{
    return a > b ? a : b;
}
double xmult(node a,node b,node c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
void init(int n)
{
    point[0][0].x =0;
    point[0][0].y =0.0;
    point[0][n+1].x=1.0;
    point[0][n+1].y=0.0;
    point[n+1][0].x=0.0;
    point[n+1][0].y=1.0;
    point[n+1][n+1].x=1.0;
    point[n+1][n+1].y=1.0;
}
node intersection(node a,node b ,node c, node d)         //求两条直线的交点
{
    node temp=a;
    double t=((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x))/((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x));
    temp.x+=(b.x-a.x)*t;
    temp.y+=(b.y-a.y)*t;
    return temp;
}
int main()
{
    int n,i,j;
    while(scanf("%d",&n),n)
    {
        init(n);
        double maxarea=0.0,temp;
        for(i=1; i<=n; i++)
        {
            scanf("%lf",&point[0][i].x);
            point[0][i].y=0;
        }
        for(i=1; i<=n; i++)
        {
            scanf("%lf",&point[n+1][i].x);
            point[n+1][i].y=1;
        }
        for(i=1; i<=n; i++)
        {
            scanf("%lf",&point[i][0].y);
            point[i][0].x=0;
        }
        for(i=1; i<=n; i++)
        {
            scanf("%lf",&point[i][n+1].y);
            point[i][n+1].x=1.0;
        }
        for(j=1; j<=n; j++)
        {
            for(i=1; i<=n; i++)
            {
                point[i][j]=intersection(point[0][j],point[n+1][j],point[i][0],point[i][n+1]);
            }
        }
        for(i=1; i<=n+1; i++)
        {
            for(j=1; j<=n+1; j++)
            {
                temp=fabs(xmult(point[i-1][j-1],point[i][j],point[i][j-1]));
                temp+=fabs(xmult(point[i-1][j-1],point[i][j],point[i-1][j]));
//abs对整数取绝对值,fabs对浮点数取绝对值
                temp/=2;
                if(maxarea < temp)
                    maxarea = temp;
            }
        }
        printf("%.6f\n",maxarea);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值