bzoj2338[HNOI2011]数矩形

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

原文地址:https://www.cnblogs.com/YuanZiming/p/5732719.html