首页 > 其他分享 >最大周长

最大周长

时间:2022-08-21 13:35:29浏览次数:71  
标签:多边形 个点 int ret leq 最大 周长

最大周长

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

这些点按顺时针顺序依次编号为 $1 \sim n$。

我们将两点 $p_1(x_1,y_1)$ 和 $p_2(x_2,y_2)$ 之间的距离定义为它们的曼哈顿距离:$d(p_1,p_2)=|x_1−x_2|+|y_1−y_2|$。

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

例如,$k$ 个点构成的多边形,其上的点按顺时针顺序依次为 $p_1,p_2, \dots, p_k$,则多边形的周长为 $d(p_1,p_2)+d(p_2,p_3)+ \dots +d(p_k,p_1)$。

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

请你计算并输出 $f(3),f(4), \dots ,f(n)$。

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

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

输入格式

第一行包含整数 $n$。

接下来 $n$ 行,每行包含两个整数 $x_i,y_i$,表示其中一个点的横纵坐标。

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

输出格式

共一行,对于每个 $i$($3 \leq i \leq n$),输出 $f(i)$。

数据范围

前 $5$ 个测试点满足 $3 \leq n \leq 10$。
所有测试点满足 $3 \leq n \leq 3 \times {10}^{5}$,${−10}^{8} \leq x_i,y_i \leq {10}^{8}$。

输入样例1:

4
2 4
4 3
3 0
1 3

输出样例1:

12 14

输入样例2:

3
0 0
0 2
2 0

输出样例2:

8

 

解题思路 

  一条边的长度是两个节点的曼哈顿距离。一个由$n$个点构成的凸多边形的周长就是相邻两点的曼哈顿距离,其实就是这个凸多边形的外接矩形的周长,如下图:

  (这性质根本想不到...)

  要想确定这个外接矩形最多需要$4$个点,上边界一个点(所有点中$y$坐标最大的值),下边界一个点(所有点中$y$坐标最小的值),左边界一个点(所有点中$x$坐标最小的值),右边界一个点(所有点中$x$坐标最大的值)。

  因此当$k \geq 4$,求由$k$个点构成的凸多边形时,我们都取这$4$个点,由它构成的矩形的周长一定是最大的(与原来的$n$个点的凸多边形的周长一样),取其他点只会让这个矩形变小。

  当$k=3$,需要特殊处理。可以发现当只能取$3$个点时,构成的矩形的周长一定会比之前的要小。这个三角形的外接矩形必定有一个点确定两条边,比如下图位于左下角的点:

  因此可以枚举每一个点,再枚举这个点是外接矩形的左下角、左上角、右上角、右下角这四种情况。当确定这点在哪个拐角处后,另外两个点也确定了,也就是另外两个边界的点(之前四个点中的两个)。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 3e5 + 10, INF = 2e9;
 5 
 6 int x[N], y[N];
 7 
 8 int main() {
 9     int n;
10     scanf("%d", &n);
11     
12     int u = -INF, d = INF, l = INF, r = -INF;
13     for (int i = 0; i < n; i++) {
14         scanf("%d %d", x + i, y + i);
15         u = max(u, y[i]), d = min(d, y[i]); // 确定上下边界
16         l = min(l, x[i]), r = max(r, x[i]); // 确定左右边界
17     }
18     
19     int ret = 0;
20     for (int i = 0; i < n; i++) {   // 3个点的情况
21         ret = max(ret, u - y[i] + r - x[i]);    // 这个点在左下角
22         ret = max(ret, y[i] - d + r - x[i]);    // 这个点在左上角
23         ret = max(ret, y[i] - d + x[i] - l);    // 这个点在右上角
24         ret = max(ret, u - y[i] + x[i] - l);    // 这个点在右下角
25     }
26     printf("%d", ret << 1);
27     
28     for (int i = 4; i <= n; i++) {  // 4个及以上个点的情况,就是n凸多边形的外接矩形的周长
29         printf(" %d", u - d + r - l << 1);
30     }
31     
32     return 0;
33 }

 

参考资料

  AcWing 4605. 最大周长(AcWing杯 - 周赛):https://www.acwing.com/video/4243/

标签:多边形,个点,int,ret,leq,最大,周长
From: https://www.cnblogs.com/onlyblues/p/16609854.html

相关文章

  • 可靠消息、最大努力通知方案
     ​可靠消息最终一致性方案指的是:当事务的发起方(事务参与者,消息发送者)执行完本地事务后,同时发出一条消息,事务参与方(事务参与者,消息的消费者) 一定能够接受消息并可以成......
  • 【队列】力扣239:滑动窗口最大值
    给定一个整数数组和一个滑动窗口大小,求在这个窗口的滑动过程中,每个时刻其包含的最大值。示例:输入:nums=[1,3,-1,-3,5,3,6,7],k=3输出:[3,3,5,5,6,7]解释:滑动窗口......
  • 通信中的数学优化| 分式规划求解和速率最大化问题(非凸)
    前言记录遇到的通信中的数学优化方法。本文所介绍的是分式规划(FractionalProgramming,FP)在以和速率最大化为目标的波束赋形问题求解中的应用。其关键思想有二:利用Lagr......
  • SqlServer 求一行中最大的时间
    需求  2种解题方法,查询结果都一样:   ......
  • 一台服务器​最大并发 TCP 连接数多少
    一台服务器​最大并发TCP连接数多少入门小站 入门小站 2022-07-0622:10 发表于湖北收录于合集#Linux485个#tcp4个首先,问题中描述的65535个连接指的是......
  • 654. 最大二叉树
    654.最大二叉树给定一个不重复的整数数组 nums。 最大二叉树 可以用下面的算法从 nums递归地构建:创建一个根节点,其值为 nums中的最大值。递归地在最大值......
  • LeetCode/最大二叉树
    给定一个不重复的整数数组nums。最大二叉树可以用下面的算法从nums递归地构建:创建一个根节点,其值为nums中的最大值递归地在最大值左边的子数组前缀上构建......
  • 网络最大流三题
    昨天杭电多校1001题人均过,该学学网络流了(虽然dls说过,网络流只能出金牌题)在b站看了电子科大的网络流入门,学会了dinic的板子,还不会严格证明求单源单汇的最大流,简单来说就是......
  • 练习8:最大公约数和最小公倍数问题
    最大公约数的计算,用到辗转相除法例如:求gcd(24,10),可以转换为gcd(10,4),然后是gcd(4,2),然后是(2,0),最好得出结果是2方法1:functiongcd(a,b){vartempif......
  • 1011 Highway 树的直径 树的最大生成树
     链接:https://ac.nowcoder.com/acm/contest/26077/1011来源:牛客网题目描述InICPCCamptherewerentownsconvenientlynumberedwith1,2,......