1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| #include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8; const double PI = acos(-1); const double INF = 1e16; inline int sgn(double x){ if(fabs(x) < eps) return 0; else if(x > 0) return 1; else return -1; } inline int cmp(double x, double y){ if(fabs(x-y) < eps) return 0; else if(x > y) return 1; else return -1; }
struct Vector{ double x, y, ang; Vector(double x = 0, double y = 0):x(x), y(y){} void read(){ scanf("%lf%lf", &x, &y); } }; typedef Vector Point; Vector operator + (Vector A, Vector B){ return Vector{A.x + B.x, A.y + B.y}; } Vector operator - (Vector A, Vector B){ return Vector{A.x - B.x, A.y - B.y}; } Vector operator * (double k, Vector A){ return Vector{k * A.x, k * A.y}; } bool operator < (const Vector &A, const Vector &B){ return cmp(A.x, B.x) == 0 ? cmp(A.y, B.y) < 0 : cmp(A.x, B.x) < 0; } double operator * (Vector A, Vector B){ return A.x * B.x + A.y * B.y; } double operator ^ (Vector A, Vector B){ return A.x * B.y - A.y * B.x; } double Length(Vector A){ return sqrt(A * A); } double Angle(Vector A){ return atan2(A.y, A.x); } bool ToTheLeft(Point A, Point B, Point C){ return sgn((B - A) ^ (C - B)) > 0; } bool ToTheLeft(Vector A, Vector B){ return sgn(A ^ B) > 0; } double TriangleArea(Point A, Point B, Point C){ return ((B - A) ^ (C - A)) / 2; }
bool cmp1(const Point &A, const Point &B){ return cmp(A.ang, B.ang) == 0 ? A * A < B * B : A.ang < B.ang; }
const int N = 55;
int T, n; Point p[N], t[N]; double dp[N][N], ans;
inline void solve(int O){ int tid = 0; for(int j = 1; j <= n; j++){ if(j == O) continue; if(cmp(p[j].y, p[O].y) < 0) continue; t[++tid] = p[j] - p[O]; t[tid].ang = Angle(p[j] - p[O]); } sort(t+1, t+tid+1, cmp1); memset(dp, 0, sizeof dp); for(int i = 1; i <= tid; i++){ for(int j = 1; j < i; j++){ if(cmp(t[j].ang, t[i].ang) == 0) continue; bool ok = true; for(int k = j + 1; k < i; k++){ if(ToTheLeft(t[j], t[k]) && ToTheLeft(t[k], t[i]) && ToTheLeft(t[i] - t[j], t[k] - t[j])){ ok = false; break; } } if(!ok) continue; double ijO = fabs(TriangleArea(Point(0, 0), t[j], t[i])); dp[i][j] = max(dp[i][j], ijO); if(sgn(t[j] ^ t[j-1]) != 0) for(int k = 1; k < j; k++) if(ToTheLeft(t[j] - t[k], t[i] - t[k])) dp[i][j] = max(dp[i][j], ijO + dp[j][k]); ans = max(ans, dp[i][j]); } } }
int main(){ scanf("%d", &T); while(T--){ scanf("%d", &n); ans = 0; for(int i = 1; i <= n; i++) p[i].read(); for(int i = 1; i <= n; i++) solve(i); printf("%.1f\n", ans); } return 0; }
|