https://codeforces.com/gym/102460/attachments
这个题可以学会O(nlogn)求外围凸包的模板。
给一堆点,选出四个点使得按某种顺序连接这4个点的四边形面积最大。点数是4096,大概是n方的复杂度。
凸包的板子是网上白剽的。
#include<bits/stdc++.h> using namespace std; const int MaxN=10010; int n,tot;//n?????,tot?????? struct point { long long x,y; }; point p[MaxN],CHP[MaxN],a[MaxN];//CHP?????????? bool cmp(point a,point b)//????,?x?????,??x??,?y?????? { return (a.x<b.x||(a.x==b.x&&a.y<b.y)); } long long xmul(point a,point b,point c)//?? { return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } void Andrew() { sort(p,p+n,cmp); tot=0; for(int i=0;i<n;++i)//??????? { while(tot>1&&xmul(CHP[tot-2],CHP[tot-1],p[i])<0) --tot; CHP[tot++]=p[i]; } int k=tot; for(int i=n-2;i>=0;--i)//??????? { while(tot>k&&xmul(CHP[tot-2],CHP[tot-1],p[i])<0) --tot; CHP[tot++]=p[i]; } if(n>1)//?????????????? --tot; } //long long odist(int i,int j){ // return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); //} //long long dist(int dian,int i,int j){ // long long A=a[i].y-a[j].y; // long long B=a[i].x-a[j].x; // long long C=0-A*a[i].x-B*a[i].y; // long long mo=sqrt(A*A+B*B); // return (A*a[dian].x+B*a[dian].y+C)/mo; //} long long chaji(int i,int j,int k){ long long x_1=a[i].x-a[j].x; long long y_1=a[i].y-a[j].y; long long x_2=a[i].x-a[k].x; long long y_2=a[i].y-a[k].y; return abs(x_1*y_2-x_2*y_1); } long long chajii(point i,point j,point k){ long long x_1=i.x-j.x; long long y_1=i.y-j.y; long long x_2=i.x-k.x; long long y_2=i.y-k.y; return abs(x_1*y_2-x_2*y_1); } const double eps=1e-6; int noton(int x){ for(int i=1;i<=tot;i++){ if(fabs(a[i].x-p[x].x)==0&&fabs(a[i].y-p[x].y)==0 )return 0; } return 1; } int main() { int t; scanf("%d",&t); while(t--){ memset(p,0,sizeof(p)); memset(CHP,0,sizeof(CHP)); memset(a,0,sizeof(a)); scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%lld%lld",&p[i].x,&p[i].y); } Andrew(); for(int i=0;i<tot;++i) { a[i+1]=CHP[i]; a[i+1+tot]=CHP[i]; } if(tot<=3){ long long ans=0; for(int i=1;i<=n;i++){ if(noton(i)){ long long jian=min( min(chajii(p[i],a[1],a[2]),chajii(p[i],a[1],a[3])) ,chajii(p[i],a[2],a[3])); ans=max(ans,chajii(a[1],a[2],a[3])-jian); } } if(ans%2)printf("%lld.5\n",ans/2); else printf("%lld\n",ans/2); } else{ long long ans=0; for(int i=1;i<=tot;i++){ int l=i,r=i; for(int j=i+1;j<=tot;j++){ r=max(r,j); long long lastr=0; while(r<=i+tot){ long long ss=chaji(r,i,j); if(ss<lastr){r--;break;} lastr=ss; r++; } if(r>i+tot)r--; l=max(l,i); long long lastl=0; while(l<=j){ long long ss=chaji(l,i,j); if(ss<lastl){l--;break;} lastl=ss; l++; } if(l>j)l--; //printf("%d %d %d %d %lf %lf\n",i,j,l,r,lastl,lastr); ans=max(ans,lastl+lastr); } } if(ans%2)printf("%lld.5\n",ans/2); else printf("%lld\n",ans/2); } } return 0; }