用向量积求线段焦点证明:
首先,我们设 (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 ",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 "); } printf("%.6lf ",maxm); /* for(int i=2;i<=n+1;i++){ for(int j=2;j<=n+1;j++) printf("%lf ",node[i][j].x); printf(" "); }*/ } }