bzoj 1069: [SCOI2007]最大土地面积
先求出凸包,旋转卡壳,可以枚举对角线,再分别找对角线两边最远的点。。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<queue> 7 #define M 100005 8 #define ll long long 9 using namespace std; 10 ll read() 11 { 12 char ch=getchar(); 13 ll x=0,f=1; 14 for(;ch<'0'||ch>'9';ch=getchar()) 15 if(ch=='-') 16 f=-1; 17 for(;ch>='0'&&ch<='9';ch=getchar()) 18 x=x*10+ch-'0'; 19 return x*f; 20 } 21 struct data 22 { 23 double x,y; 24 }a[M],s[M]; 25 data operator -(data a1,data a2) 26 { 27 data a3; 28 a3.x=a1.x-a2.x; 29 a3.y=a1.y-a2.y; 30 return a3; 31 } 32 double operator *(data a1,data a2) 33 { 34 return a1.x*a2.y-a1.y*a2.x; 35 } 36 double dis(data a1,data a2) 37 { 38 return (a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y); 39 } 40 bool cmp(data a1,data a2) 41 { 42 int t=(a1-a[1])*(a2-a[1]); 43 if(t==0) 44 return dis(a1,a[1])<dis(a2,a[1]); 45 return t<0; 46 } 47 int n,tot; 48 double ans; 49 int main() 50 { 51 n=read(); 52 for(int i=1;i<=n;i++) 53 scanf("%lf%lf",&a[i].x,&a[i].y); 54 int q=1; 55 for(int i=2;i<=n;i++) 56 if(a[i].y<a[q].y||(a[i].y==a[q].y&&a[i].x<a[q].x)) 57 q=i; 58 swap(a[1],a[q]); 59 sort(a+2,a+n+1,cmp); 60 s[1]=a[1]; 61 s[2]=a[2]; 62 tot=2; 63 for(int i=3;i<=n;i++) 64 { 65 for(;tot>1&&(a[i]-s[tot-1])*(s[tot]-s[tot-1])<=0;tot--); 66 s[++tot]=a[i]; 67 } 68 s[tot+1]=s[1]; 69 for(int x=1;x<=tot;x++) 70 { 71 int a=x%tot+1,b=(x+2)%tot+1; 72 for(int y=x+2;y<=tot;y++) 73 { 74 for(;a%tot+1!=y&&(s[y]-s[x])*(s[a]-s[x])<(s[y]-s[x])*(s[a+1]-s[x]);a=a%tot+1); 75 for(;b%tot+1!=x&&(s[b]-s[x])*(s[y]-s[x])<(s[b+1]-s[x])*(s[y]-s[x]);b=b%tot+1); 76 ans=max(ans,(s[b]-s[x])*(s[y]-s[x])+(s[y]-s[x])*(s[a]-s[x])); 77 } 78 } 79 printf("%.3lf",ans/2); 80 return 0; 81 }