Pipeline

 

Pipeline

 

Time Limit:   1000MS       Memory Limit:   65535KB
Submissions:   1109       Accepted:   263

 

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

 

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

 

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

 

Sample Input

 

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

 

Sample Output

 

6

解析:
题意很好理解,就题上的测试用例,我可以得到如下图

那么测试数据的结果就是图中红色线段的和,因此就用计算y坐标到平行于x轴的直线y=m的最短距离
就有dis=|y0-m|+|y1-m|+|y2-m|+|y3-m|+```+|yn-m|,这个很容易就看出:当m取y0```yn的中点时,dis最小;如果不是很清楚,可以画如下线段函数图象,就一目了然了

因此要得到中点y坐标只需先对y1```yn进行排序,取中间值即可,代码如下:
# include<stdio.h>
# include<math.h>
# include<algorithm>
using namespace std;
int main()
{
    int nCoord;
    int x[10005],y[10005];
    int i,midy,ans=0;
    scanf("%d",&nCoord);
    for(i=0;i<nCoord;i++)
        scanf("%d %d",&x[i],&y[i]);
    sort(y,y+nCoord);
    midy=y[nCoord/2];
    for(i=0;i<nCoord;i++)
        ans+=abs(y[i]-midy);
    printf("%d\n",ans);
    return 0;
}


 

 

 

Soldiers

Time Limit:   1000MS       Memory Limit:   65535KB
Submissions:   609       Accepted:   180

 

Description
在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名士兵。按照军官的命令,士兵们要整齐地列成一个水平队列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何选择x 和y的值才能使士兵们以最少的总移动步数排成一列。 计算使所有士兵排成一行需要的最少移动步数。
Input
第1 行是油井数n,1< =n< =10000。接下来n 行是油井的位置,每行2个整数x和y,-10000< =x,y< =10000。
Output
第1 行中的数是士兵排成一行需要的最少移动步数。

Sample Input

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

Sample Output

8

解析:
这道题上面那道题很相似,只是多了x坐标的排序,并需要对x坐标进行一点转换,由于y和上面一样,x是disx=|x0-midx|+|x1-(midx+1)|+···+|xn-(midx+n)|=|x0-midx|+|(x1-1)-midx|+···+|(xn-n)-midx|,因此先转换tx=xi-i,在对tx排序即可,如下:
# include<stdio.h>
# include<math.h>
# include<algorithm>
using namespace std;
int main()
{
    int nCoord;
    int x[10005],y[10005],tx[10005];
    int i,midtx,midy,ans=0;
    scanf("%d",&nCoord);
    for(i=0;i<nCoord;i++)
        scanf("%d %d",&x[i],&y[i]);
    sort(x,x+nCoord);
    sort(y,y+nCoord);
    for(i=0;i<nCoord;i++)
        tx[i]=x[i]-i;
    sort(tx,tx+nCoord);
    midtx=tx[nCoord/2];
    midy=y[nCoord/2];
    for(i=0;i<nCoord;i++)
    {
        ans+=abs(tx[i]-midtx);
        ans+=abs(y[i]-midy);
    }
    printf("%d\n",ans);
    return 0;
}

 

PostOffice

 

Time Limit:   1000MS       Memory Limit:   65535KB
Submissions:   318       Accepted:   97

 

Description
  在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。用x 坐标表示东西向,用y坐标表示南北向。各居民点的位置可以由坐标(x,y)表示。   街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值|x1-x2|+|y1-y2|度量。   居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。   任务:给定n 个居民点的位置,编程计算n 个居民点到邮局的距离总和的最小值。

 

Input
  第1 行是居民点数n,1 < = n < =10000。接下来n 行是居民点的位置,每行2 个整数x 和y,-10000 < =x,y < =10000。

 

Output
n 个居民点到邮局的距离总和的最小值。

 

Sample Input

 

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

 

Sample Output

 

10

 

解析:

这是多点到一个点的问题,只需像第一题一样,对x和y排序,取中点即可

 

# include<stdio.h>
# include<math.h>
# include<algorithm>
using namespace std;
int main()
{
    int nCoord;
    int x[10005],y[10005];
    int i,midy,midx,ans=0;
    scanf("%d",&nCoord);
    for(i=0;i<nCoord;i++)
        scanf("%d %d",&x[i],&y[i]);
    sort(x,x+nCoord);
    sort(y,y+nCoord);
    midx=x[nCoord/2];
    midy=y[nCoord/2];
    for(i=0;i<nCoord;i++)
    {
        ans+=abs(x[i]-midx);
        ans+=abs(y[i]-midy);
    }
    printf("%d\n",ans);
    return 0;
}

 

 

 

posted on 2013-03-09 13:59  即为将军  阅读(375)  评论(0)    收藏  举报

导航