//总是感觉生活很空虚,就只能写写博客看看书上上课这样子。想出去,去一个遥远的地方。
先来看一下题目:
有n户人家坐落在从西向东的一条街上。从街西头向东数,第i户的房子与街西头的距离是H[i]米,(1≤i≤n), H[1]< H[2] < H[3] … < H[n] ,假设街上没有邮局。现在,要在街上建一些邮局使得任一户人家到最近一个邮局的距离不超过1000米。请设计一个O(n)时间的算法以确定最少需要见的邮局收,并给出每个邮局到街西头的距离。
看到这道算法题,我有点羡慕这条街的人,寄信肯定超级方便,但也不禁有疑问,这个年代还要不要设置这么多邮局,因为不知道是不是还有很多人在写信,但是我特想写封信寄给她。蓦然想起来那首《从前慢》,"从前的日色变得慢/车,马,邮件都慢/一生只够爱一个人"。
正所谓一步一个脚印,既然要建邮局,还是那么多邮局,我们必然要从第一个邮局建起,邮局我们就假设为一个P数组,int型,里面存储邮局距离街最西头王大姐家菜地的距离。那么,第一个邮局便是P[1],回顾一下题目,我们需要确定最少的邮局数量,也就是说我们要让邮局的存在效用最大化,即每个邮局的覆盖范围最广,那么对P[1]来讲,必然是P[1]设立在H[1]+1000处时最为合适,附图来说:
从图里面可以看出,P[1]设立在H[1]+1000处时覆盖范围最广,在此点的右边设立,不符合题意,第一户人家距离邮局太远,若在左边,那么范围不够大,会多出第一户人家到菜地的一些距离,这个距离对邮局设立来说意义不大。将第一个邮局设立之后,应当考虑P[2],P[3]...假若H[2]等一些户人家在段1或者段2之中,那么我们便无需再对这些人家考虑单独设立邮局,直到距离P[1]+1000点最近且在此点东边的下一户人家重新开始考虑设立P[2],方法与H[1]和P[1]相同,以此类推到P[n]。
这里要注意的是,按照算法,最后一户人家如果距离其左边的邮局距离大于千米,那么在其右边千米处会设立一个邮局,也就是在街的最东头设立了一个邮局,这就有点尴尬了,专门为最后一户人家设立的还距离那么远。因此我们将此邮局设立在最后一户人家附近即可。
下面给出代码:
#include<stdio.h>
#define MAX 101
int Post_office(int P[],int H[],int n){
P[1]=H[1]+1000; //第一个邮局位置
int m=1;
int i;
for(i=2;i<=n;i++){
if(H[i]>P[m]+1000){
m++;
P[m]=H[i]+1000;
}
}
if(P[m]>H[n])
P[m]=H[n]; //最后一个邮局不需要在最后一户人家之外
return m;
}
int main(){
int P[MAX];
int H[MAX];
int n=0;
int m=0;
printf("Please input the quantity:\n");
scanf("%d",&n);
printf("Please input the family`s distance:\n");
for(int i=1;i<=n;i++){
scanf("%d",&H[i]);
}
m=Post_office(P,H,n);
printf("There are %d post office,there are:\n",m);
for(int i=1;i<=m;i++){
printf("%d ",P[i]);
}
return 0;
}