求出所有交点枚举每个四边形找最大面积即可。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAXN = 40; 8 9 const double eps = 1e-10; 10 11 struct Point 12 { 13 double x, y; 14 Point( double x = 0, double y = 0 ):x(x), y(y) { } 15 }; 16 17 typedef Point Vector; 18 19 Vector operator+( Vector A, Vector B ) //向量加 20 { 21 return Vector( A.x + B.x, A.y + B.y ); 22 } 23 24 Vector operator-( Vector A, Vector B ) //向量减 25 { 26 return Vector( A.x - B.x, A.y - B.y ); 27 } 28 29 Vector operator*( Vector A, double p ) //向量数乘 30 { 31 return Vector( A.x * p, A.y * p ); 32 } 33 34 Vector operator/( Vector A, double p ) //向量数除 35 { 36 return Vector( A.x / p, A.y / p ); 37 } 38 39 bool operator<( const Point& A, const Point& B ) //两点比较 40 { 41 return A.x < B.x || ( A.x == B.x && A.y < B.y ); 42 } 43 44 int dcmp( double x ) //控制精度 45 { 46 if ( fabs(x) < eps ) return 0; 47 else return x < 0 ? -1 : 1; 48 } 49 50 double Dot( Vector A, Vector B ) //向量点乘 51 { 52 return A.x * B.x + A.y * B.y; 53 } 54 55 double Length( Vector A ) //向量模 56 { 57 return sqrt( Dot( A, A ) ); 58 } 59 60 double Angle( Vector A, Vector B ) //向量夹角 61 { 62 return acos( Dot(A, B) / Length(A) / Length(B) ); 63 } 64 65 double Cross( Vector A, Vector B ) //向量叉积 66 { 67 return A.x * B.y - A.y * B.x; 68 } 69 70 double Area2( Point A, Point B, Point C ) //向量有向面积 71 { 72 return Cross( B - A, C - A ); 73 } 74 75 Vector Rotate( Vector A, double rad ) //向量旋转 76 { 77 return Vector( A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad) ); 78 } 79 80 Point GetLineIntersection( Point P, Vector v, Point Q, Vector w ) //两直线交点 81 { 82 Vector u = P - Q; 83 double t = Cross( w, u ) / Cross( v, w ); 84 return P + v * t; 85 } 86 87 bool SegmentProperIntersection( Point a1, Point a2, Point b1, Point b2 ) //线段相交,交点不在端点 88 { 89 double c1 = Cross( a2 - a1, b1 - a1 ), c2 = Cross( a2 - a1, b2 - a1 ), 90 c3 = Cross( b2 - b1, a1 - b1 ), c4 = Cross( b2 - b1, a2 - b1 ); 91 return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0; 92 } 93 94 bool OnSegment( Point p, Point a1, Point a2 ) //点在线段上,不包含端点 95 { 96 return dcmp( Cross(a1 - p, a2 - p) ) == 0 && dcmp( Dot( a1 - p, a2 - p ) ) < 0; 97 } 98 99 Point P[4][MAXN]; 100 Point ch[MAXN][MAXN]; 101 102 void init( int n ) 103 { 104 ch[0][0].x = 0.0, ch[0][0].y = 0.0; 105 ch[0][n + 1].x = 1.0, ch[0][n + 1].y = 0.0; 106 ch[n + 1][0].x = 0.0, ch[n + 1][0].y = 1.0; 107 ch[n + 1][n + 1].x = 1.0, ch[n + 1][n + 1].y = 1.0; 108 109 for ( int i = 1; i <= n; ++i ) 110 ch[0][i] = P[0][i]; 111 for ( int i = 1; i <= n; ++i ) 112 ch[n + 1][i] = P[1][i]; 113 for ( int i = 1; i <= n; ++i ) 114 ch[i][0] = P[2][i]; 115 for ( int i = 1; i <= n; ++i ) 116 ch[i][n + 1] = P[3][i]; 117 118 for ( int i = 1; i <= n; ++i ) 119 for ( int j = 1; j <= n; ++j ) 120 ch[i][j] = GetLineIntersection( P[2][i], P[3][i] - P[2][i], P[0][j], P[1][j] - P[0][j] ); 121 122 return; 123 } 124 125 int main() 126 { 127 int n; 128 while ( scanf( "%d", &n ), n ) 129 { 130 for ( int i = 0; i < 4; ++i ) 131 { 132 for ( int j = 1; j <= n; ++j ) 133 { 134 double a; 135 scanf( "%lf", &a ); 136 switch( i ) 137 { 138 case 0: 139 P[i][j].x = a; 140 P[i][j].y = 0.0; 141 break; 142 case 1: 143 P[i][j].x = a; 144 P[i][j].y = 1.0; 145 break; 146 case 2: 147 P[i][j].x = 0.0; 148 P[i][j].y = a; 149 break; 150 case 3: 151 P[i][j].x = 1.0; 152 P[i][j].y = a; 153 break; 154 } 155 } 156 } 157 158 init( n ); 159 160 double ans = 0.0; 161 for ( int i = 0; i <= n; ++i ) 162 for ( int j = 0; j <= n; ++j ) 163 { 164 Point a = ch[i][j], b = ch[i][j + 1], c = ch[i + 1][j + 1], d = ch[i + 1][j]; 165 double area = fabs( Cross( b-a, c-a )/2.0 ) + fabs( Cross( c-a, d-a )/2.0 ); 166 if ( area > ans ) ans = area; 167 } 168 169 printf( "%.6f ", ans ); 170 171 } 172 return 0; 173 }