Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 1642 | Accepted: 1051 |
Description
Input
Output
Sample Input
2 0.2000000 0.6000000 0.3000000 0.8000000 0.1000000 0.5000000 0.5000000 0.6000000 2 0.3333330 0.6666670 0.3333330 0.6666670 0.3333330 0.6666670 0.3333330 0.6666670 4 0.2000000 0.4000000 0.6000000 0.8000000 0.1000000 0.5000000 0.6000000 0.9000000 0.2000000 0.4000000 0.6000000 0.8000000 0.1000000 0.5000000 0.6000000 0.9000000 2 0.5138701 0.9476283 0.1717362 0.1757412 0.3086521 0.7022313 0.2264312 0.5345343 1 0.4000000 0.6000000 0.3000000 0.5000000 0
Sample Output
0.215657 0.111112 0.078923 0.279223 0.348958
题意:在一个边长为1的正方形(如图)的四个边上分别插入n个点,上和下,左和右分别对应点相连构成若干个线段,这些线段相交之后构成若干个四边形,问最大的那个四边形的面积;
先将对应点连起来构成线段,求出各个交点,这样就可以根据叉乘求出每个四边形的面积,比较之后得出最大的。我开始存输入的点的坐标时用的一位数组,结果找四边形对应顶点时就很麻烦,还是没想全面。改成二维数组后,p[i][j]就表示第i行第j个点的坐标,这样找四边形顶点坐标就好找了;
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 5 const double eps = 1e-8; 6 int cmp(double x) 7 { 8 if(fabs(x) < eps) 9 return 0; 10 if(x > 0) return 1; 11 return -1; 12 } 13 14 struct point 15 { 16 double x,y; 17 point(){} 18 point(double a,double b):x(a),y(b) {} 19 friend point operator - (const point &a, const point &b) 20 { 21 return point(a.x-b.x,a.y-b.y); 22 } 23 friend point operator * (const double &a, const point &b) 24 { 25 return point(a*b.x,a*b.y); 26 } 27 friend point operator / (const point &a, const double &b) 28 { 29 return point(a.x/b,a.y/b); 30 } 31 }p[50][50];//p[i][j]存第i行第j列交点处的点的坐标; 32 33 struct line 34 { 35 point a,b; 36 line (){} 37 line(point x, point y):a(x),b(y) {} 38 }L[50][50];//存线段; 39 40 double det(const point &a, const point &b) 41 { 42 return a.x * b.y - a.y * b.x; 43 } 44 bool parallel(line a,line b) 45 { 46 return !cmp(det(a.a-a.b,b.a-b.b)); 47 } 48 bool line_make_point(line a,line b,point &res) 49 { 50 if(parallel(a,b)) return false; 51 double s1 = det(a.a-b.a,b.b-b.a); 52 double s2 = det(a.b-b.a,b.b-b.a); 53 res = (s1*a.b-s2*a.a)/(s1-s2); 54 return true; 55 } 56 double area(point a[]) 57 { 58 double sum = 0; 59 a[4] = a[0]; 60 for(int i = 0; i < 4; i++) 61 sum += det(a[i+1],a[i]); 62 return sum/2; 63 } 64 int main() 65 { 66 int n; 67 while(~scanf("%d",&n) && n) 68 { 69 for(int i = 1; i <= n; i++) 70 { 71 scanf("%lf",&p[0][i].x); 72 p[0][i].y = 0; 73 } 74 p[0][0].x = 0; 75 p[0][0].y = 0; 76 p[0][n+1].x = 1; 77 p[0][n+1].y = 0; 78 79 for(int i = 1; i <= n; i++) 80 { 81 scanf("%lf",&p[n+1][i].x); 82 p[n+1][i].y = 1; 83 } 84 p[n+1][0].x = 0; 85 p[n+1][0].y = 1; 86 p[n+1][n+1].x = 1; 87 p[n+1][n+1].y = 1; 88 89 for(int i = 1; i <= n; i++) 90 { 91 scanf("%lf",&p[i][0].y); 92 p[i][0].x = 0; 93 } 94 for(int i = 1; i <= n; i++) 95 { 96 scanf("%lf",&p[i][n+1].y); 97 p[i][n+1].x = 1; 98 } 99 for(int i = 1; i <= n; i++) 100 { 101 L[i][0].a = p[0][i]; 102 L[i][0].b = p[n+1][i]; 103 } 104 for(int i = 1; i <= n; i++) 105 { 106 L[0][i].a = p[i][0]; 107 L[0][i].b = p[i][n+1]; 108 } 109 110 for(int i = 1; i <= n; i++) 111 { 112 for(int j = 1; j <= n; j++) 113 line_make_point(L[0][i],L[j][0],p[i][j]);//横着第i条线段与竖着第j条线段的交点保存在p[i][j]中 114 } 115 116 double max = eps; 117 for(int i = 1; i <= n+1; i++) 118 { 119 for(int j = 1; j <= n+1; j++) 120 { 121 point t[10]; 122 t[0] = p[i][j-1]; 123 t[1] = p[i][j]; 124 t[2] = p[i-1][j]; 125 t[3] = p[i-1][j-1];//顺时针四个点的坐标; 126 double sum = area(t); 127 if(sum > max) 128 max = sum; 129 } 130 } 131 printf("%.6lf\n",max); 132 } 133 return 0; 134 }