几何问题 poj 1408

参考博客:

用向量积求线段焦点证明:

首先,我们设 (AD向量 × AC向量) 为 multi(ADC) ; 那么 S三角形ADC = multi(ADC)/2 。

由三角形DPD1 与 三角形CPC1 相似;可得 |DP| / |PC| = |DD1| / |CC1| = multi(ADB) × multi(ACB) 。

|DP| / |PC| = (xD - xP) / (xP - xC) = (yD - yP) / (yP - yC) 。

xP = ((multi(D,B,A) * xC - multi(C,B,A) * xD)) / (multi(D,B,A) - multi(C,B,A));

yP = ((multi(D,B,A) * yC - multi(C,B,A) * yD)) / (multi(D,B,A) - multi(C,B,A));

题目不难,大致题意为:

给定一个单位矩阵,并在每条边上面“嵌入”n个点,这样每条边共有n+2个点。将单位矩阵对面相应位置的点连接起来,构成n*n个不规则四边形。要求出这n*n个矩阵中面积的最大值。

简单的模拟+叉积求三角形面积+不规则四边形划分成三角形求面积。

枚举每个四边形,将每个四边形划分为2个三角形。利用三角形求面积公式计算面积。比较求出最大面积。

那么关键点在于如何求三角形面积。

下面提供2中方法:

1)解析几何:

海伦公式: S=p*(p-a)*(p-b)*(p-c)取根号,其中p=(a+b+c)/2;

2)计算几何方法

S=1/2*| ac向量 叉乘 ab向量|

显然,计算几何方法更快,且精度更高(没有根号),代码也少,而且在求线段交点的过程中也会用到叉乘。一举两得

另外在模拟的过程中,要格外小心,因为很多细节要注意。
代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<math.h>
using namespace std;
const int max_=40;
typedef struct point{
   double x;
   double y;
}point;
point node[max_][max_];
double det(double x1,double y1,double x2,double y2)
{
    return x1*y2-x2*y1;
}
double cross(point A,point B,point P)//AB,AP的叉乘
{
    return det(B.x-A.x,B.y-A.y,P.x-A.x,P.y-A.y);
}
void intersection(point A,point B,point C,point D,int i,int j)//两线段的交点坐标
{
    double nulti1=cross(A,B,C);
    double nulti2=cross(A,B,D);
    //printf("%lfok\n",nulti1);
    node[i][j].x=(nulti2*C.x-nulti1*D.x)/(nulti2-nulti1);
    node[i][j].y=(nulti2*C.y-nulti1*D.y)/(nulti2-nulti1);
}
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {
        node[1][1].x=0.0,node[1][1].y=1.0;
        node[1][n+2].x=1.0,node[1][n+2].y=1.0;
        node[n+2][1].x=0.0,node[n+2][1].y=0.0;
        node[n+2][n+2].x=1.0,node[n+2][n+2].y=0.0;
        for(int i=2;i<=n+1;i++)
        {
            scanf("%lf",&node[n+2][i].x);
            node[n+2][i].y=0.0;
        }
        for(int i=2;i<=n+1;i++)
        {
            scanf("%lf",&node[1][i].x);
            node[1][i].y=1.0;
        }
        for(int i=n+1;i>=2;i--)
        {
            scanf("%lf",&node[i][1].y);
            node[i][1].x=0.0;
        }
        for(int i=n+1;i>=2;i--)
        {
            scanf("%lf",&node[i][n+2].y);
            node[i][n+2].x=1.0;
        }
        for(int i=2;i<=n+1;i++)
            for(int j=2;j<=n+1;j++)
        {
            intersection(node[i][1],node[i][n+2],node[1][j],node[n+2][j],i,j);
        }
        double maxm=-1.0;
        for(int i=1;i<=n+1;i++)
            for(int j=1;j<=n+1;j++)//两三角形面积和
        {
            double temp=fabs(cross(node[i][j],node[i+1][j],node[i][j+1]))*0.5+
                        fabs(cross(node[i+1][j+1],node[i+1][j],node[i][j+1]))*0.5;
                        if(maxm<temp)
                            maxm=temp;
                       //     printf("ok\n");
        }
        printf("%.6lf\n",maxm);
       /* for(int i=2;i<=n+1;i++){
            for(int j=2;j<=n+1;j++)
            printf("%lf ",node[i][j].x);
            printf("\n");
        }*/
    }
}

猜你喜欢

转载自www.cnblogs.com/linhaitai/p/9818208.html