bzoj2338[HNOI2011]数矩形
题意:
n个顶点,找一个矩形,使其面积最大。注意:矩形的边不一定要和坐标轴平行!
题解:
先将点两两组成线段,然后将它们按中点和长度排序,则每组中点和长度都相等的线段两两都可以组成矩形,比较它们的面积就行。求面积用叉积(即两个向量末端点与它们的和末端点组成的平行四边形的面积,公式:x1*y2-x2*y1或|a|*|b|*sin<a,b>)除以2。反思:本蒟蒻正因为红字部分WA了,而且本题的数据似乎并没有那么大,才能这样写。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <set> 5 #define inc(i,j,k) for(int i=j;i<=k;i++) 6 #define maxn 2000 7 #define ll long long 8 using namespace std; 9 10 inline ll sqr(ll a){return a*a;} 11 struct line{ll x1,y1,x2,y2;}; line lines[maxn*maxn]; int linen; 12 inline ll length(line a){return sqr(a.x1-a.x2)+sqr(a.y1-a.y2);} 13 bool cmp(line a,line b){ 14 if(a.x1+a.x2==b.x1+b.x2&&a.y1+a.y2==b.y1+b.y2) 15 return length(a)<length(b); 16 else return a.x1+a.x2==b.x1+b.x2?a.y1+a.y2<b.y1+b.y2:a.x1+a.x2<b.x1+b.x2; 17 } 18 ll x[maxn],y[maxn]; int n; 19 int main(){ 20 scanf("%d",&n); inc(i,1,n)scanf("%lld%lld",&x[i],&y[i]); linen=0; 21 inc(i,1,n)inc(j,i+1,n)lines[++linen]=(line){x[i],y[i],x[j],y[j]}; 22 sort(lines+1,lines+1+linen,cmp); ll mx=0; 23 inc(i,1,linen-1){ 24 line &a=lines[i]; int j=i+1; 25 while(j<=linen&&length(a)==length(lines[j])&&a.x1+a.x2==lines[j].x1+lines[j].x2&&a.y1+a.y2==lines[j].y1+lines[j].y2) 26 mx=max(mx,abs((a.x2-a.x1)*(lines[j].y2-lines[j].y1)-(a.y2-a.y1)*(lines[j].x2-lines[j].x1))>>1),j++; 27 } 28 printf("%lld",mx); return 0; 29 }
20160520