zoukankan      html  css  js  c++  java
  • 「SDOI2012」最近最远点对

    传送门

    由于本人比较菜,所以只写了个旋转坐标系的做法 (Q omega Q)

    旋转坐标系的原理很显然,我们考虑到离得最近的两个点,它们的横坐标之差肯定也不会大,离得最远的同理。

    但是我们肯定还是不能 naive 地直接去算,为了更好地保证正确性,我们可以随机旋转坐标系。

    虽然操作不好会 T ,不过这题确实还是稳过的。

    参考代码:

    #include <algorithm>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <ctime>
    using namespace std;
    
    const double pi = acos(-1.0);
    const int _ = 2e5 + 5;
    
    int n; double mn = 1e18, mx = 0;
    struct node { double x, y; } t[_];
    int cmp(node a, node b) { return a.x < b.x; }
    
    double dist(node a, node b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); }
    
    void calc(double d) {
        d = d / 180.0 * pi;
        for (int i = 1; i <= n; ++i) {
            double x = t[i].x, y = t[i].y;
            t[i].x = x * cos(d) - y * sin(d);
            t[i].y = x * sin(d) + y * cos(d);
        }
        sort(t + 1, t + n + 1, cmp);
        for (int i = 1; i <= n; ++i)
            for (int j = i + 1; j <= min(i + 10, n); ++j)
                mn = min(mn, dist(t[i], t[j]));
        for (int i = 1; i <= min(10, n); ++i)
            for (int j = max(1, n - 9); j <= n; ++j)
                mx = max(mx, dist(t[i], t[j]));
    }
    
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("cpp.in", "r", stdin), freopen("cpp.out", "w", stdout);
    #endif
        srand(time(0));
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) scanf("%lf %lf", &t[i].x, &t[i].y);
        calc(0);
        calc(rand() % 360);
        calc(rand() % 360);
        printf("%.5lf %.5lf
    ", mn, mx);
        return 0;
    }
    
  • 相关阅读:
    【Leetcode】113Path Sum II
    【leetcode】112. Path Sum
    virtualbox 中安装win7虚拟机
    制作一个vagrant的win7 box
    socket编程
    异常处理
    strip(),replace()和re.sub()用法
    面象对象 高阶篇
    面象对象 基础篇
    Subprocess模块介绍
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/13162558.html
Copyright © 2011-2022 走看看