分治算法例题

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

目录

1031 输油管道问题 (1)

解题思路 (1)

程序代码 (1)

1032 邮局选址 (4)

解题思路 (4)

程序源代码 (4)

1034 集合划分2 (6)

解题思路: (6)

程序源代码: (6)

1033 集合划分 (8)

解题思路 (8)

程序源代码 (8)

1031 输油管道问题

解题思路

本题目可以分为两个步骤:

1、找出主管道得位置;

2、根据主管道得位置,计算各个油井到主管道得长度之与。

根据题意,设主管道贯穿东西,与y 轴平行。而各个子油井则分布在主输油管道得上下两侧。如下图:

由上图,其实只需要确定主管道得y 坐标,而与各个子油井得x 坐标无关!根据猜测,易知:主管道得y 坐标就就是所有子油井y 坐标得中位数。(可以用平面几何知识证明,略)

求中位数得方法可以用排序后取a[(left+right)/2],当然更推荐用书上得线性时间选择算法解决。记求得得主管道为,最后要输出得结果只需要计算:,输出即可。

另外要提醒得就是本题多Case。

程序代码

#include

#include

void s &a,int &b)

{

int tmp = a;

a = b;

b = tmp;

}

//本函数求arr[p:q]得一个划分i,使arr[p:i-1]都小于arr[i],arr[i+1,q]都大于arr[i]

int partition(int *arr,int p,int q)

{

int index = p-1,start = p,base = arr[q];

for(;start

{

if(arr[start]<=base)

{

s[start],arr[++index]);

}

}

s[++index],arr[q]);

return index;

}

//快速排序

void qsort(int *arr,int p ,int q)

{

if(p<=q)

{

int pos = partition(arr,p,q);

qsort(arr,p,pos-1);

qsort(arr,pos+1,q);

}

}

int arr[10001];

int main()

{

int n;

//注意多case 写法

while(scanf("%d",&n)!=EOF)

{

//读取数据

for(int i=0;i

{

//读取y

scanf("%d %d",&arr[i],&arr[i]);

}

//排序

qsort(arr,0,n-1);

//取中位数得下标mid,然后计算距离

long long sum = 0;

int mid = arr[n/2];

for(int i=0;i

{

sum += abs(mid - arr[i]);

}

printf("%I64d\n",sum);

}

return 0;

}

1032 邮局选址

解题思路

本题与上一题非常类似,这次就是要找出在居民点中邮局得最佳位置。很容易想到,这次不仅要确定y 坐标,还要确定x 坐标。类似猜想可以知道,邮局最佳位置应该为:

等于所有居民点x坐标得中位数;

等于所有居民点y 坐标得中位数;

分别求中位数得过程与上题类似,不再陈述。最终得计算结果:要求距离之与,输出。

程序源代码

#include

#include

#include

using namespace std;

int x[10000],y[10000];

int main()

{

int n;

while(scanf("%d",&n)!=EOF)

{

//读取x 与y 坐标

for(int i=0;i

{

scanf("%d %d",&x[i],&y[i]);

}

//调用STL中得排序算法,分别对x 坐标与y 坐标进行排序

sort(x,x+n);

sort(y,y+n);

//取x,y 坐标得中位数并计算距离

int midx = x[n/2];

int midy = y[n/2];

long long res = 0;

for(int i = 0;i < n;i++)

{

res += abs(midx-x[i]);

res += abs(midy-y[i]);

}

// 输出结果

printf("%I64d\n",res);

}

return 0;

}

1034 集合划分2

解题思路:

递推公式如下:

F (n,m) =m*F (n −1,m)+F (n −1,m −1)

F(n,m)表示把n 个元素得集合分为m 个子集,有多少种分法。

证明如下:

n 个元素得集合可以划分为F(n,m)个不同得由m 个非空子集组成得集合。考虑3 个元素得集合,可划分为

相关文档
最新文档