题目大意:
给出m个坐标和n个坐标,n个坐标的横坐标都比m个坐标的横坐标要来的小。求出从m个坐标中选出一个坐标,要使得它到n个坐标中的其中一个坐标的汉明距离达到最小。
思路:
汉明距离:abs(x1 - x2) + abs(y1 - y2)
由于任意的x1 < x2,所以变成x1 - x2 + abs(y1 - y2)
下面分情况进行讨论:
y1 >= y2的情况,x1 - x2 + y1 - y2 即 x1 + y1 -(x2 + y2)
y1 < y2 的情况,x1 - x2 + y2 - y1 即x1 - y1 + y2 - x2
那么就需要维护-(x2 + y2)达到最小,(y2 -x2)达到最小
然后再维护x1 + y1 -(x2 + y2)达到最小,x1-y1 + y2 -x2达到最小
代码:
#include <iostream>
using namespace std;
#include <cstring>
#include <stdio.h>
#include <algorithm>
const int N = 200010;
const int INF = 0x3f3f3f3f;
struct points {
int x,y,flag;
}P[N];
int n,m;
bool cmp(points a, points b) {
return a.y < b.y;
}
void init() {
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d %d",&P[i].x,&P[i].y);
P[i].flag = 0;
}
scanf("%d",&m);
for(int i = 0; i < m ; i++) {
scanf("%d %d",&P[i + n].x,&P[i + n].y);
P[i + n].flag = 1;
}
}
int solve() {
int ans = INF;
int tmp = INF;
sort(P,P + n + m,cmp);
for(int i = 0; i < n + m; i++) {
if(P[i].flag)
tmp = min(tmp,P[i].x - P[i].y);
else
ans = min(ans,tmp + P[i].y - P[i].x);
}
tmp = INF;
for(int i = 0; i < n + m; i++) {
if(P[i].flag)
ans = min(ans, P[i].x + P[i].y + tmp);
else
tmp = min(tmp,-(P[i].x + P[i].y));
}
return ans;
}
int main() {
int kase;
scanf("%d",&kase);
while(kase--) {
init();
printf("%d\n",solve());
}
return 0;
}