飞花的传送门

飞花的传送门

TimeLimit: 1000ms Memory limit: 65536K

题目描述

飞花壕最近手头比较宽裕,所以想买两个传送门来代步(夏天太热,实在是懒得走路)。平面上有N个传送门,飞花壕想要挑两个距离最远的传送门带回家(距离为欧几里得距离,即两点之间直线距离)。

请你帮他算一算他所挑选的最远的两个传送门有多远。

输入

多组输入。

对于每组输入,第一行输入一个整数N2<= N <= 50000),接下来从第2行到第N+1行,每行两个整数(XiYi),代表第i个传送门的坐标(-1000000<= Xi , Yi <= 1000000)。

数据为随机生成。

输出

输出一个整数,代表飞花壕要挑选的两个传送门的距离的平方。

示例输入

4

00

01

11

10

示例输出

2

/*
校赛的一道题,开始不知道什么意思,比完后听他们说是凸包;
*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

typedef long long LL;

const int Max=51000;

struct node
{
    LL x;
    LL y;
}point[Max],AA[Max];
LL py,px;
bool cmp(node a,node b)
{
    return atan2(a.y-py, a.x-px) < atan2(b.y-py, b.x-px);
}

double compare(double x1,double y1,double x2,double y2)
{
    return x1*y2-x2*y1;
}

double compare(int a,int b,int c)
{
    return compare(AA[b].x-AA[a].x,AA[b].y-AA[a].y,point[c].x-AA[a].x,point[c].y-AA[a].y);
}

LL dis(int a,int b)
{
    return (AA[a].x-AA[b].x)*(AA[a].x-AA[b].x)+(AA[a].y-AA[b].y)*(AA[a].y-AA[b].y);
}

int main()
{
    int n;
    int top;
    LL sum;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {
            scanf("%lld %lld",&point[i].x,&point[i].y);
            if(i)
            {
                if(py>point[i].y)
                {
                    py=point[i].y;
                    px=point[i].x;
                }
                else if(py==point[i].y&&px>point[i].x)
                {
                    px=point[i].x;
                }
            }
            else
            {
                py=point[i].y;
                px=point[i].x;
            }
        }

        sort(point ,point+n, cmp);

        AA[0]=point[0];
        AA[1]=point[1];
        top=1;
        for(int i=2;i<n;)
        {
            if(top&&compare(top-1,top,i)<=0)
            {
                top--;
            }
            else
            {
                AA[++top]=point[i++];
            }
        }
        while(compare(top-1,top,0)<=0)
        {
            top--;
        }
        sum=0;
        LL ans;
        for(int i=0;i<=top;i++)
        {
            for(int j=i+1;j<=top;j++)
            {
                ans=dis(i,j);
                if(sum<ans)
                {
                    sum=ans;
                }
            }
        }
        printf("%lld\n",sum);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值