题意
有N行M列的格点,C个朋友分别住在位于格点的C家酒店里,有H家饭店,现在他们要选择一家饭店使得C个朋友中距离这家饭店曼哈顿距离最大的人距离最小,问要选择哪家饭店,这个距离是多少
思路
二分答案,验证可行性时是对每个朋友的活动范围取交,这个活动范围是由平行于x+y=a和x-y=b的四条线围成的矩形,取完交后也是由平行于这两条线的四条线围成的矩形或没有,判断是不是有饭店在这个里边就行,也是根据x+y和x-y的范围判断
代码
#include <cstdio>
#include <algorithm>
using namespace std;
long long x1[100001],y1[100001],x2[100001],y2[100001];
long long N,M,C,H,ans1,ans2;
long long check(long long len)
{
long long addleft=0;
long long addright=N+M;
long long minusleft=-max(M,N);
long long minusright=max(M,N);
for(long long i=1;i<=C;i++)
{
addleft=max(addleft,x1[i]+y1[i]-len);
addright=min(addright,x1[i]+y1[i]+len);
minusleft=max(minusleft,x1[i]-y1[i]-len);
minusright=min(minusright,x1[i]-y1[i]+len);
}
for(long long i=1;i<=H;i++)
if(x2[i]+y2[i]>=addleft&&x2[i]+y2[i]<=addright&&x2[i]-y2[i]>=minusleft&&x2[i]-y2[i]<=minusright)
return i;
return 0;
}
long long binary_search(long long l,long long r)
{
if(l==r)
return l;
if(r-l==1)
{
if(check(l))
return l;
else return r;
}
long long mid=(l+r)/2;
if(check(mid))
return binary_search(l,mid);
else return binary_search(mid+1,r);
}
int main()
{
scanf("%I64d%I64d",&N,&M);
scanf("%I64d",&C);
for(long long i=1;i<=C;i++)
scanf("%I64d%I64d",&x1[i],&y1[i]);
scanf("%I64d",&H);
for(long long i=1;i<=H;i++)
scanf("%I64d%I64d",&x2[i],&y2[i]);
ans1=binary_search(0,N+M);
ans2=check(ans1);
printf("%I64d\n%I64d\n",ans1,ans2);
return 0;
}