uvalive5848

题目大意:
给出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;
}

你可能感兴趣的:(uvalive5848)