街区最短路径问题
时间限制:3000 ms | 内存限制:65535 KB
难度:4
-
描述
- 一个街区有很多住户,街区的街道只能为东西、南北两种方向。
住户只可以沿着街道行走。
各个街道之间的间隔相等。
用(x,y)来表示住户坐在的街区。
例如(4,20),表示用户在东西方向第4个街道,南北方向第20个街道。
现在要建一个邮局,使得各个住户到邮局的距离之和最少。
求现在这个邮局应该建在那个地方使得所有住户距离之和最小;
-
输入
- 第一行一个整数n<20,表示有n组测试数据,下面是n组数据;
每组第一行一个整数m<20,表示本组有m个住户,下面的m行每行有两个整数0<x,y<100,表示某个用户所在街区的坐标。
m行后是新一组的数据;
输出 - 每组数据输出到邮局最小的距离和,回车结束; 样例输入
-
2 3 1 1 2 1 1 2 5 2 9 5 20 11 9 1 1 1 20
样例输出 -
2 44
- 第一行一个整数n<20,表示有n组测试数据,下面是n组数据;
由于所以的道路都是水平或者垂直的,只能在水平和竖直方向上行走,水平方向和竖直方向分别考虑互不影响,平均值点即为所求。
代码如下:
01.
#include<stdio.h>
02.
int
abs
(
int
a)
03.
{
04.
if
(a<0)
return
-a;
05.
else
return
a;
06.
}
07.
int
main()
08.
{
09.
int
m,n,i,j,x,y,right,left,sum,k[100],t[100];
10.
scanf
(
"%d"
,&m);
11.
for
(i=0;i<m;i++)
12.
{
13.
scanf
(
"%d"
,&n);
14.
15.
for
(j=0;j<100;j++)k[j]=t[j]=0;
16.
17.
for
(j=0;j<n;j++)
18.
{
19.
scanf
(
"%d%d"
,&right,&left);
20.
k[right]++;
21.
t[left]++;
22.
}
23.
24.
n=(n+1)/2;
25.
sum=0;
26.
for
(j=0;j<100;j++)
27.
{
28.
if
(k[j])
sum+=k[j];
29.
if
(sum>=n)
break
;
30.
}
31.
x=j;
32.
33.
sum=0;
34.
for
(j=0;j<100;j++)
35.
{
36.
if
(t[j])
sum+=t[j];
37.
if
(sum>=n)
break
;
38.
}
39.
y=j;
40.
41.
42.
sum=0;
43.
for
(j=0;j<100;j++)
44.
{
45.
if
(k[j])sum+=k[j]*
abs
(x-j);
46.
if
(t[j])sum+=t[j]*
abs
(y-j);
47.
}
48.
printf
(
"%d\n"
,sum);
49.
}
50.
}