洛谷 P1862 输油管道问题

洛谷 P1862 输油管道问题

如果只有一口井,那么显然是越近越好。如果有两口井,那么显然是有以下三种情况:

  • 两口井都在主管道北边,那么这个时候的两个连接管道的长度和肯定大于两口井的Y坐标之差。

  • 两口井都在主管道南边,和情况1是一样的

  • 两口井,一个在主管道南边,一个在主管道北边,那么两个连接管道的长度和就等于两口井的Y坐标之差。

显然情况三是所要的最短管道的设计情况。就是当主管道在两口井之间的任意位置时,连接管道长度之和都等于两口井的Y坐标之差,是最短的长度。

那么将这个结论推广,当有n口井的时候,

  • n是偶数 只要这n口井分布在主管道的两边,一边n/2个,那么就是距离之和最小的。

  • n是奇数,只要将这n个井中,Y坐标最中间的(也就是Y是中值的那个)井不算,其余的偶数个井分布在主管道的两侧,这个时候移动主管道,那么这n个连接管道长度之和就决定于那个没有算的井了,因为其余的井的距离之和是固定了的,这个时候只要主管道最接近那个点就好了。

也就是说,输油管道的位置就是最中间的那口井(或中间的区间)。我的方法是将各口井的y坐标排序(x坐标不用管),再取 n div 2+1 的位置,即最中间的位置。

#include <bits/stdc++.h>
using namespace std;

const int N = 10005;
/*
文件名:petroleum
题目:洛谷 P1862 输油管道问题
题目网址:https://www.luogu.com.cn/problem/P1862

输入:
5
1 2
2 2
1 3
3 -2
3 3
输出:
6
*/

int n, a[N]; // a[0..n-1]。第i口油井的纵坐标在a[i]

int main() {
    // 输入数据
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i] >> a[i]; // 横坐标说没有用的,可以直接抛弃掉

    // 排序
    sort(a, a + n);

    // 两端对称取长短。中位数原理。
    int sum = 0;
    for (int i = 0, j = n - 1; i <= j; i++, j--) sum += a[j] - a[i];

    cout << sum << endl;
    return 0;
}

posted @   糖豆爸爸  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2022-09-19 哈夫曼编码HuffmanCoding原理详解
2022-09-19 22张图带你深入剖析前缀、中缀、后缀表达式以及表达式求值
2021-09-19 P2615 神奇的幻方
2016-09-19 关于云主机拷贝复制资源异常的处理办法
Live2D
点击右上角即可分享
微信分享提示