问题描述
某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。
如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置?
给定n口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和。
输入
第1行是一个整数n,表示油井的数量(1≤n≤10 000)。
接下来n行是油井的位置,每行两个整数x和y
(﹣10 000≤x,y≤10 000)。
输出
各油井到主管道之间的输油管道最小长度总和。
输入样例

5
1 2
2 2
1 3
3 -2
3 3

输出样例

6


解题思路:
设n口油井的位置分别为
,i=1~n。由于主输油管道是东西向的,因此可用其主轴线的y坐标唯一确定其位置。主管道的最优位置y应该满足:

由中位数定理可知,y是中位数。

算法1:对数组a排序(一般是升序),取中间的元素。
int n;                  //油井的数量
int x;                  //x坐标,读取后丢弃
int a[1000];                //y坐标
cin>>n;
for(int k=0;k<n;k++)cin>>x>>a[k];
sort(a,a+n);               //按升序排序
//计算各油井到主管道之间的输油管道最小长度总和
int min=0;
for(int i=0;i<n;i++)min += (int)fabs(a[i]-a[n/2]);
cout<<min<<endl;
算法2:采用分治策略求中位数。
int n;                  //油井的数量
int x;                  //x坐标,读取后丢弃
int a[1000];                //y坐标
cin>>n;
for (int i=0; i<n; i++)cin>>x>>a[i];
int y = select(0, n-1, n/2);       //采用分治算法计算中位数
//计算各油井到主管道之间的输油管道最小长度总和
int min=0;
for(int i=0;i<n;i++)min += (int)fabs(a[i]-y);
cout<<min<<endl;
//select子函数(详情请见https://blog.csdn.net/qq_53549930/article/details/123240562)
int select(int left, int right, int k)
{//找到了第k小的元素if (left >= right) return a[left];int i = left;      //左侧int j = right+1;     //右侧int pivot = a[left];   //把最左侧的元素作为分界数据while (true)       //快速排列交换数据循环{do {                  //左侧i = i+1;} while (a[i] < pivot);do {                  //右侧j = j-1;} while (a[j] > pivot);if (i >= j) break;swap(a[i], a[j]);}if (j-left+1 == k) return pivot;a[left] = a[j];a[j] = pivot;if (j-left+1 < k)//对一个段进行递归调用return select(j+1, right, k-j+left-1);    //找右边else return select(left, j-1, k);     //找左边
}

输油管道问题--递归相关推荐

  1. 输油管道或水井挖水渠中路径和最短问题

    1.问题描述 修建输油管道或者挖水渠,方向都是指向正南正北或者正东正西.然后有多个油井或者水井需要向管道或者水渠修建小分支管道或者水渠,求输油管道或者水渠的位置,使得所有的油管小分支长度总和最小或者所 ...

  2. 分治策略——输油管道问题

    分治策略 1.分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同. 2.递归地解这些子问题 ...

  3. 7-2 输油管道问题

    某石油公司计划建造一条由东向西的主输油管道.该管道要穿过一个有n 口油井的油田.从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连.如果给定n口油井的位置,即它们的x 坐标(东西向)和y ...

  4. C++:分治算法之输油管道问题

    目录 描述 输入 输出 输入样例 输出样例 分析 代码 运行结果 描述 ¢ 某石油公司计划建造一条 由东向西 的主输油管道.该管道要穿过一个有n口油井的油田.从每口油井都要有一条输油管道沿最短路经(或 ...

  5. 算法设计思想(5)— 递归法

    1. 递归概念 递归 Recursion是指在函数的定义中使用函数自身的方法,直观上来看,就是某个函数自己调用自己. ​ 递归有两层含义: 递归问题必须可以分解为若干个规模较小.与原问题形式相同的子问 ...

  6. 判断某数组是不是二叉树的后序遍历序列 python递归与非递归解法

    python 递归 class Solution:def VerifySquenceOfBST(self, sequence):# write code hereif len(sequence) &l ...

  7. 翻转二叉树 c语言实现 递归 栈 队列

    前言 题目比较好理解,就是翻转二叉树 代码 c语言实现 #include<stdio.h> #include<stdlib.h> #include<string.h> ...

  8. 快速排序的递归和非递归实现 c语言版本

    代码 挖坑法 解释 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列第一个数为枢轴,也是初始的坑位. 设置两个变量i = l;j = r;其中l = 0, r = ...

  9. LeetCode 10. Regular Expression Matching python特性、动态规划、递归

    前言 本文主要提供三种不同的解法,分别是利用python的特性.动态规划.递归方法解决这个问题 使用python正则属性 import reclass Solution2:# @return a bo ...

最新文章

  1. Java程序员三年的工作经验,却不如一个新人的工资高???
  2. Kubernetes(基础 一):进程
  3. mysql中使用join exists in时该注意的问题
  4. vue 事件总线EventBus的概念、使用以及注意点
  5. Exchange系列—使用系统自带的备份工具来备份数据库
  6. InfoPath开发经验小节
  7. 硬件芯片选型原理图设计
  8. Spring定时器的运用
  9. VirtualBox不能共享剪贴板,有两种情形
  10. android获取GPS权限
  11. LittleVGL--07lv_obj基础对象介绍、API 接口、例程演示
  12. bittorrent+sync+java_使用BitTorrent-Sync实现双机文件双向同步
  13. 解决MySql保存数据java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x91\x87\xE5\x91...‘
  14. gitlab-ci配置
  15. 向量法计算体积的思路(没有代码了)
  16. java9新特性-4-模块化系统: Jigsaw与Modularity
  17. “百花齐放”电商时代,网易七鱼打造专业电商客服
  18. Zabbix如何配置告警短信?
  19. 【CV系列】基于直方图的白天夜晚场景判断算法
  20. 火狐浏览器和ie_浏览器趋势2016年5月:Firefox最终超过IE

热门文章

  1. leetcode-递增的三元子序列推广到递增的X元子序列
  2. JS事件汇总,addEventListener添加事件监听
  3. 分不清?!Sketch Measure 和 Sketch Meaxure 有什么区别?
  4. 书籍推荐!张磊首部力作《价值》
  5. Naive script setup写法上传注意
  6. IM即时通讯H信 Android
  7. 《H3C交换机配置与管理完全手册》(第二版)前言和目录
  8. 2021年科技园区规划设计方案
  9. 史上最全PPT制作教程和PPT模板,毕业论文答辩PPT制作方法
  10. Python入门基础(六) 字典