最大周长问题

目录

题目描述

解法


题目描述

给定二维平面上的 nn 个不共线的点,这 nn 个点组成的多边形是凸多边形 。

这些点按顺时针顺序依次编号为 1∼n1∼n。

我们将两点 p1(x1,y1)p1(x1,y1) 和 p2(x2,y2)p2(x2,y2) 之间的距离定义为它们的曼哈顿距离:d(p1,p2)=|x1−x2|+|y1−y2|d(p1,p2)=|x1−x2|+|y1−y2|。

此外,我们将多边形的周长定义为其上所有相邻点对之间的曼哈顿距离之和。

例如,kk 个点构成的多边形,其上的点按顺时针顺序依次为 p1,p2,…,pkp1,p2,…,pk,则多边形的周长为 d(p1,p2)+d(p2,p3)+…+d(pk,p1)d(p1,p2)+d(p2,p3)+…+d(pk,p1)。

对于每个 kk(3≤k≤n3≤k≤n),请你考虑,从给定的 nn 个点中任选 kk 个点,构成一个多边形,要求多边形不能是自相交的并且其周长要尽可能长,用 f(k)f(k) 来表示周长的最大可能值。

请你计算并输出 f(3),f(4),…,f(n)f(3),f(4),…,f(n)。

注意,多边形不可以自相交,且边必须是直的,例如下图中:

位于中间的多边形无效,因为是自相交多边形;位于右边的多边形无效,因为边不是直的,只有左边的多边形是有效的。

输入格式

第一行包含整数 nn。

接下来 nn 行,每行包含两个整数 xi,yixi,yi,表示其中一个点的横纵坐标。

所有点的坐标两两不同,且点是按照顺时针排列给出的。

输出格式

共一行,对于每个 ii(3≤i≤n3≤i≤n),输出 f(i)f(i)。

数据范围

前 55 个测试点满足 3≤n≤103≤n≤10。
所有测试点满足 3≤n≤3×10^5    3≤n≤3×10^5,−10^8≤xi,yi≤10^8。

解法

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 300010,INF=1e9;
int n;
int x[N],y[N];

int main()
{
    int u=-INF,d=INF,l=INF,r=-INF;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&x[i],&y[i]);
        d=min(d,y[i]),u=max(u,y[i]);
        l=min(l,x[i]),r=max(r,x[i]);
    }
    int res = 0;
    for(int i=0;i<n;i++){
        res=max(res,max(u-y[i],y[i]-d)+max(x[i]-l,r-x[i]));
    }
    cout<<res*2<<" ";
    for(int i=4;i<=n;i++){
        cout<<2*(u-d+r-l)<<" ";
    }
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值