NJU 输油管道线性问题

输油管道问题

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte 总提交:129            测试通过:71

描述

某石油公司计划建造一条由东向西的主输油管道。该管道要穿过一个有n 口油井的油田。从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连。如果给定n口油井的位置,即它们的x坐标(东西向)和y坐标(南北向),应如何确定主管道的最优位置,即使各油井到主管道之间的输油管道长度总和最小的位置?证明可在线性时间内确定主管道的最优位置。 给定n 口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和。

输入

输入的第1 行是油井数n,1<=n<=10000。接下来n行是油井的位置,每行2个整数x和y,-10000<=x,y<=10000。

输出

输出的第1行中的数是油井到主管道之间的输油管道最小长度总和。

样例输入

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

样例输出

6

题目来源

南京邮电大学OJ 1206

 

很简单的一个找中位数问题。

思路:①从两个油井的情况入手,不妨假设主管道都在油井的南边或北边,那么油井到主管道距离之和肯定大于等于两个油井之间的y坐标之差。

            ②再假设主管道位于两口井中间,那么可以知道无论主管道怎么移动,油井到主管道的距离之和都是两口井的y坐标之差。

            ③把两口井推广到n口井上:

            1.n是奇数,那么只要将主管道覆盖到最中间油井所在东西走向的直线就可以得到,距离之和是剩下偶数个油井南边y坐标减北边y坐标的

差的绝对值之和。

            2.n是偶数。直接得到结论。

           ④由此一来,问题就转移到了求众多油井y坐标中位数的问题了。

 

 代码如下:C语言(AC通过代码)

View Code
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5 int *p,*q;
 6 int sum=0;
 7 int mid;           //线性查找的中位数
 8 int temp;
 9 int n,i,j;
10 scanf("%d",&n);
11 p=(int*)malloc(n*sizeof(int));
12 q=(int*)malloc(n*sizeof(int));
13 for(i=0;i<n;i++)scanf("%d%d",&p[i],&q[i]);
14 for(i=0;i<n-1;i++)
15   for(j=i+1;j<n;j++)
16       if(q[i]<q[j]){temp=q[i];q[i]=q[j];q[j]=temp;}
17 
18 if(n%2==0)
19 {
20  for(i=0;i<n/2;i++)
21  sum=sum+q[i]-q[i+n/2];
22 }
23 else
24 {
25  for(i=0;i<n/2;i++)
26  sum=sum+q[i]-q[i+n/2+1];
27 }
28 printf("%d\n",sum);
29 free(p);
30 free(q);
31 
32 }

 

 

 

posted @ 2012-12-25 15:34  jaki2012  阅读(242)  评论(0)    收藏  举报