邮局选址问题
Time Limit:1000MS Memory Limit:65536K
Total Submit:147 Accepted:82
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
对应每组输入,输出的第1 行中的数是n 个居民点到邮局的距离总和的最小值。
Sample Input
5 1 2 2 2 1 3 3 -2 3 3
Sample Output
10
从这里找到了解答:http://www.khgl.cn/html/07/n-1000407.html
因为街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值 |x1-x2 |+ |y1-y2 |度量;
那么:
邮局的x坐标只与n个居民点的x坐标相关;
邮局的y 坐标只与n个居民点的y坐标相关;
下面以求x坐标为例,y坐标的求法类似;
假设对n个居民点的x坐标按大小排序后为x1,x2....xi...xn;
对x1,xn两点来说,最近的点肯定在x1,xn之间,且跟两点的距离和==xn-x1;
对x2,x(n-1)两点来说,最近的点肯定在x2,x(n-1)之间,且跟两点的距离和==x(n-1)-x2;
....
所以若n为奇数,则邮局的x坐标取最中间的值时最小;
所以若n为偶数,则邮局的x坐标可以取最中间两个值的之间的任意值;
最终公式:x=(x(n/2+1)+x(n/2+2)+...+xn)-(x1+x2+..+x(n/2))
最终公式:
s=(x(n/2+1)+x(n/2+2)+...+xn)-(x1+x2+..+x(n/2))
+(y(n/2+1)+y(n/2+2)+...+yn)-(y1+y2+..+y(n/2))
源代码
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAX_SIZE = 10005;
bool cmp(int a, int b)
{
if(a < b)
return true;
else
return false;
}
int cal(int str[], int n)
{
int sum = 0,i,mid;
mid = str[n / 2];
for(i = 0; i < n; i++)
sum += abs(str[i] - mid);
return sum;
}
int main()
{
int x[MAX_SIZE],y[MAX_SIZE];
int i, n;
while(scanf("%d",&n) != EOF)
{
for(i = 0; i < n; i++)
scanf("%d%d",x + i, y + i);
sort(x ,x + n, cmp);
sort(y, y + n, cmp);
printf("%d\n",cal(x, n) + cal(y, n));
}
return 0;
}