目录
题目描述
给定二维平面上的 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;
}