(几何)n个点中找4个点求能组成正方形的最大面积

在2019年3月底的团体程序设计天梯赛后,16级队员正式退役了,有的队员迅速找到了一份满意而体面的工作,有的队员估摸一算发现自己好像能保研了,还有一些队员则是在考研的道路上一往无前所向披靡,而有的队员懵在原地,不知所措。

WYS作为实验室中一个细心观察生活中点点滴滴的人,她很快就发现了实验室中某些人的状态很不对劲,常常呆在某个位置发呆,于是她向LZX,YXY等人询问情况,而却苦于心情难以用言语表达,决定由肢体语言表达出自己的心情----我很方,非常方。

作为一名实验室中考研人群中的一员,WYS发现自己似乎没有很多时间去处理这些问题,于是他把这个问题交给了你,希望你能够给出正确的答案。

我们简化问题,实验室有n(1<=n<=3000)个呆在原地的人,他们被看做为平面上的整数点(x,y)(1<=x,y<=5000),要表达出他们有多方,一共需要满足两个条件:

        1.组成一个正方形,只有特殊的正方形才能说明他们非常方

        2.组成的正方形尽可能大

即我们要找到平面上四个人组成的最大的正方形面积为多少?

 

配图.jpg

如上图所示,在平面上组成了两个正方形面积S1和S2,显然S1的面积更大一些,所以对于此时,答案为5

输入描述

第1行为一个整数n表示平面上有多少个站在原地不动的人

第2行到第n+1行有两个数,分别为xi,yi表示第i名原地不动的人的坐标 

 

输出描述

输出一个数即最大正方形面积(若无法构成任意一个正方形,则输出-1)

样例输入

8
2 1 
1 3
4 2
3 4
5 1
5 3
6 2
7 4

样例输出

5

题解 : 枚举两个点,确定另外两个点。

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=(tree[rt<<1],tree[rt<<1|1]);
#define nth(k,n) nth_element(a,a+k,a+n);  // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,离散化
#define Catalan C(2n,n)-C(2n,n-1)  (1,2,5,14,42,132,429...) // 卡特兰数
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const double pi = atan(1.)*4.;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int M=63;
const int N=1e5+5;
int n;
struct fun{
    int x,y;
}f[3005];

bool mapp[5005][5005];

bool fun(int x1,int y1,int x2,int y2){
    int d1=abs(x1-x2); int d2=abs(y1-y2);
    if(x1>=x2&&y1>=y2){     //  (x1,y1) 在 (x2,y2) 的第一象限
        int yy2=y2+d1;
        int xx2=x2-d2;
        int yy1=y1+d1;
        int xx1=x1-d2;
        //printf("%d %d %d %d\n",xx1,yy1,xx2,yy2);
        if(xx1>=1&&yy1>=1&&xx2>=1&&yy2>=1&&xx1<=5000&&yy1<=5000&&xx2<=5000&&yy2<=5000&&mapp[xx1][yy1]&&mapp[xx2][yy2])
            return true;
        xx2=x2+d2;
        yy2=y2-d1;
        xx1=x1+d2;
        yy1=y1-d1;
       // printf("%d %d %d %d %d %d\n",xx1,yy1,xx2,yy2,mapp[xx1][yy1],mapp[xx2][yy2]);
        if(xx1>=1&&yy1>=1&&xx2>=1&&yy2>=1&&xx1<=5000&&yy1<=5000&&xx2<=5000&&yy2<=5000&&mapp[xx1][yy1]&&mapp[xx2][yy2])
            return true;
    }
    else if(x1>=x2&&y1<=y2){    //  (x1,y1) 在 (x2,y2) 的第四象限
        int yy2=y2+d1;
        int xx2=x2+d2;
        int yy1=y1+d1;
        int xx1=x1+d2;

        if(xx1>=1&&yy1>=1&&xx2>=1&&yy2>=1&&xx1<=5000&&yy1<=5000&&xx2<=5000&&yy2<=5000&&mapp[xx1][yy1]&&mapp[xx2][yy2])
            return true;
        xx2=x2-d2;
        yy2=y2-d1;
        xx1=x1-d2;
        yy1=y1-d1;
        if(xx1>=1&&yy1>=1&&xx2>=1&&yy2>=1&&xx1<=5000&&yy1<=5000&&xx2<=5000&&yy2<=5000&&mapp[xx1][yy1]&&mapp[xx2][yy2])
            return true;
    }
    return false;
}
int main(){
    scanf("%d",&n);
    int leap=0;
    memset(mapp,0,sizeof(mapp));
    for(int i=0;i<n;i++){
        scanf("%d %d",&f[i].x,&f[i].y);
        mapp[f[i].x][f[i].y]=true;
    }
    ll ans=-1;
    for(int i=0;i<n;i++){
        for(int j=i+1;j<n;j++){
            int xx1=f[i].x,yy1=f[i].y;
            int xx2=f[j].x,yy2=f[j].y;
            if(xx1<=xx2){          //  (x1,y1) 在 (x2,y2) 的第二,三象限
                swap(xx1,xx2);
                swap(yy1,yy2);
            }
            if(fun(xx1,yy1,xx2,yy2)){
               // printf("YES\n");
                leap=1;
                ll d=(f[i].y-f[j].y)*(f[i].y-f[j].y)+(f[i].x-f[j].x)*(f[i].x-f[j].x);
                //printf("(%d %d)  (%d %d)   d == %lld\n",f[i].x,f[i].y,f[j].x,f[j].y,d);
                ans=max(ans,d);
            }
        }
    }
    if(leap) printf("%lld\n",ans);
    else printf("-1\n");
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值