输油管道问题(分治策略)

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

编程任务:
给定n 口油井的位置,编程计算各油井到主管道之间的输油管道最小长度总和.

1、sort()排序

 1 //输油管道问题
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 int a[10005];
 9 int main(){
10     int x,n;
11     cin>>n;
12     for( int i = 0; i < n; i++ )
13         cin>>x>>a[i];
14     sort(a,a+n);
15     int min = 0;
16     for( int i = 0; i < n; i++ )
17         min += fabs(a[i]-a[n/2]);
18     cout<<min<<endl;
19     return 0;
20 } 

2、select()选择

 1 //输油管道问题
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>//sort(),swap()
 7 using namespace std;
 8 int a[10005];
 9 
10 int select(int left,int right,int k){
11     if( left >= right )
12         return a[left];
13     int x = a[left];
14     int i = left;
15     int j = right+1;
16     while( true ){
17         do{
18             i++;
19         }while(a[i]<x);
20         do{
21             j--;
22         }while(a[j]>x);
23         if(i>=j)
24             break ;
25         swap(a[i],a[j]);
26     }
27     if( j-left+1 == k )
28         return x;
29     a[left] = a[j];
30     a[j] = x;
31     if( j-left+1 < k )
32         return select(j+1,right,k-j+left-1);
33     else
34         return select(left,j-1,k);
35 }
36 
37 int main(){
38     int n,x,y;
39     cin>>n;
40     for( int i = 0; i < n; i++ )
41         cin>>x>>a[i];
42     y = select(0,n-1,n/2);
43     int min = 0;
44     for( int i = 0; i < n; i++ )
45         min += fabs(a[i] - y);
46     cout<<min<<endl;
47     return 0;
48 }

原文地址:https://www.cnblogs.com/geziyu/p/10029935.html