拉练紧急集合
Description
军训是大学一门必修的课程。相信大家记忆最深刻的项目一定是“夜晚十公里拉练”。
凌晨1点,警钟拉响,所有同学需要以最快的时间到达紧急集合点。
众所周知,我理校园里的道路都是横平竖直的,所以我们将我理的地图抽象为网格图,任意两点的距离可以看作二维曼哈顿距离。
宿舍楼散布在校园的各个角落,宿舍所在位置用坐标点(x,y)表示。
教官在学校预设了多个紧急集合点,警报拉响后,同学们需要前往一个集合点报道,集合点同样用坐标点(x,y)表示。
假设所有同学的跑步速度相同,单位时间内移动单位距离。
现需要确定一个集合点使所有同学完成集合所需的时间最短,问最短时间。
Input
第一行输入两个整数 n,m(1 ≤ n,m ≤ 10^9)表示校园的大小;
第二行输入一个整数 c(1 ≤ c ≤ 10^5)表示宿舍楼的数量;
接下来 c 行,每行输入两个整数xi,yi(0 ≤ xi ≤ n)(0 ≤ yi ≤ m)表示第 i 栋宿舍的位置;
下一行输入一个整数 d(1 ≤ d ≤ 10^5)表示预设集合点的数量;
接下来 d 行,每行输入两个整数aj,bj(0 ≤ aj ≤ n)(0 ≤ bj ≤ m)表示第 j 个预设集合点的位置;
Output
请输出一个整数,表示完成集合所需的最短时间。
Hint
二维曼哈顿距离:点(x1,y1)和点(x2,y2)的曼哈顿距离是:|x1-x2| + |y1-y2| 。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int comp(const void*a, const void*b)
{
return *(int *)a-*(int *)b;
}
int cmp(const void*a, const void*b)
{
return *(int *)b-*(int *)a;
}
int main()
{
long m,n;
int c,d,i,j;
scanf("%ld %ld",&n,&m);
long x[100000]={0},y[100000]={0},a[100000]={0},b[100000]={0};
long xjiay[100000]={0},xjiany[100000]={0},fuxjiany[100000]={0},yjianx[100000]={0};
long h[100000]={0},k[100000]={0},p[100000]={0},q[100000]={0},e[100000]={0};
scanf("%d",&c);
for(i=0;i<c;i++) scanf("%ld %ld",&x[i],&y[i]);
scanf("%d",&d);
for(i=0;i<d;i++) scanf("%ld %ld",&a[i],&b[i]);
for(i=0;i<c;i++)
{
xjiay[i]=x[i]+y[i];
xjiany[i]=x[i]-y[i];
fuxjiany[i]=-x[i]-y[i];
yjianx[i]=y[i]-x[i];
}
qsort(xjiay,c,sizeof(long),cmp);
qsort(xjiany,c,sizeof(long),cmp);
qsort(fuxjiany,c,sizeof(long),cmp);
qsort(yjianx,c,sizeof(long),cmp);
for(i=0;i<d;i++)
{
h[i]=xjiay[0]-a[i]-b[i];
k[i]=xjiany[0]-a[i]+b[i];
p[i]=yjianx[0]+a[i]-b[i];
q[i]=fuxjiany[0]+a[i]+b[i];
if(h[i]>=k[i]&&h[i]>=p[i]&&h[i]>=q[i])
e[i]=h[i];
else if(k[i]>=h[i]&&k[i]>=p[i]&&k[i]>=q[i])
e[i]=k[i];
else if(p[i]>=h[i]&&p[i]>=k[i]&&p[i]>=q[i])
e[i]=p[i];
else if(q[i]>=h[i]&&q[i]>=k[i]&&q[i]>=p[i])
e[i]=q[i];
}
qsort(e,d,sizeof(long),comp);
printf("%ld\n",e[0]);
}