bzoj 2338: [HNOI2011] 직사각형(형상 계산)

7055 단어 계산 기하학

제목 설명


전송문


제목 대의: n개의 점을 제시하고 정점이 모두 n개의 점 중의 최대 직사각형을 구한다.

문제풀이


코드

#include
#include
#include
#include
#include
#define N 1503
#define LL long long 
using namespace std;
int n,cnt,top,st[N*N];
struct data{
    LL x,y;
    data(LL X=0,LL Y=0) {
        x=X,y=Y;
    }
}p[N]; 
data operator -(data a,data b){
    return data(a.x-b.x,a.y-b.y);
}
LL pow(LL x){
    return x*x;
}
struct line{
    LL x,y; LL len;
    double ang; int a,b;
    line(int A=0,int B=0) {
        a=A,b=B; x=p[a].x+p[b].x; y=p[a].y+p[b].y;
        len=pow(p[a].x-p[b].x)+pow(p[a].y-p[b].y);
        ang=atan2(p[b].y-p[a].y,p[b].x-p[a].x);
    }
}l[N*N];
int cmp(line a,line b){
    return a.x.x||a.x==b.x&&a.y.y||a.x==b.x&&a.y==b.y&&a.len.len||
           a.x==b.x&&a.y==b.y&&a.len==b.len&&a.ang.ang;   
}
bool check(line a,line b)
{
   return a.x==b.x&&a.y==b.y&&a.len==b.len;
}
LL cross(data a,data b){
    return a.x*b.y-a.y*b.x;
}
LL squ(line i,line j)
{
    data v=p[i.a]-p[j.a];
    data u=p[i.b]-p[j.a];
    return abs(cross(v,u));
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld%lld",&p[i].x,&p[i].y);
    cnt=0;
    for (int i=1;i<=n;i++)
     for (int j=i+1;j<=n;j++)
      l[++cnt]=line(i,j);
    sort(l+1,l+cnt+1,cmp);
    LL ans=0;
    for (int i=1,j;i<=cnt;i=j+1) {
        j=i;
        top=0;
        while (j<=cnt&&check(l[i],l[j])) {
            st[++top]=j;
            j++;
        }
        j--;
        int tail=1;
        for (int k=1;k<=top;k++) {
            int c=tail;
            while (squ(l[st[tail]],l[st[k]])st[tail%top+1]],l[st[k]])){
                tail=tail%top+1;
                if (tail==c) break;
            }
            ans=max(ans,squ(l[st[tail]],l[st[k]]));
        }
    }
    printf("%lld
"
,ans); }

좋은 웹페이지 즐겨찾기