解题报告 『Raid(分治)』

原题地址

大概翻译一下题目:

在与联邦的战争接连失败之后,帝国方面撤退到了最后的据点。凭借着强大的防御系统,帝国军击退了联邦的六波进攻。经过几天不眠不休的思考,Arthur,联邦统帅,注意到防御系统的唯一弱点是它的能源供应。该系统由n个核电站进行充电,任何一个核电站的故障都会导致系统失效。

将军很快就发动了一次突袭,突袭者是准备潜行进入要塞的n名特工。不幸的是,由于帝国空军的攻击,他们未能按照预期的位置着陆。作为一名经验丰富的将军,Arthur很快意识到他需要重新安排计划。他现在想知道的第一件事是哪个特工离任何一个发电站最近。大副,你能帮将军解决这个问题吗?

 

其实就是求最近点对,只不过两个点必须处于不同的集合,用分治乱搞一下就过了。

 

代码实现如下:

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (register int i = (a); i <= (b); i++)

const int inf = 0x3f3f3f3f, maxn = 1e5 + 5;

int T, n;
double ans;

struct node {
    int x, y, id;
}p[maxn], q[maxn];

int cmp_x(node a, node b) {return a.x < b.x;}

int cmp_y(node a, node b) {return a.y < b.y;}

int ABS(int a, int b) {return a > b ? a - b : b - a;}

double MIN(double a, double b) {return a < b ? a : b;}

int read() {
    int x = 0, flag = 0;
    char ch = ' ';
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') {
        flag = 1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 1) + (x << 3) + ch - '0';
        ch = getchar();
    }
    return flag ? -x : x;
}

double dis(node a, node b) {
    if (a.id == b.id) return inf;
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double divide(int l, int r) {
    if (l == r) return inf;
    int cnt = 0, mid = (l + r) >> 1;
    double ans = MIN(divide(l, mid), divide(mid + 1, r));
    rep(i, l, r)
        if (ABS(p[i].x, p[mid].x) <= ans)
            q[++cnt] = p[i];
    sort(q + 1, q + cnt + 1, cmp_y);
    rep(i, 1, cnt)
        rep(j, 1, cnt)
            if (ABS(q[i].y, q[j].y) <= ans) //复制粘贴时忘了把mid改成j,快调吐血了才发现这个傻逼错误.
                ans = MIN(ans, dis(q[i], q[j]));
    return ans;  
}

int main() {
    T = read();
    while (T--) {
        n = read();
        rep(i, 1, n << 1) {
            p[i].x = read(), p[i].y = read();
            if (i <= n) p[i].id = 0;
            else p[i].id = 1;
        }
        sort(p + 1, p + (n << 1) + 1, cmp_x);
        ans = divide(1, n << 1);
        printf("%.3f\n", ans);
    }
    return 0;
}
View Code
posted @ 2019-05-10 12:12  雲裏霧裏沙  阅读(373)  评论(0编辑  收藏  举报