zoukankan      html  css  js  c++  java
  • Codeforces Round #231 (Div. 2) E.Lightbulb for Minister

    题意:有n个点,问在一个m边形内哪个点与这n个点的距离平方和最小

    题解:(ai-a0)^2=ai*ai+a0*a0-a*ai*a0

    合起来就是a1*a1+...+an*an+n*a0*a0-2*a0*(a1+...+an)

    取导数就是2*n*a0-2*a0*(a1+...+an)

    可以知道在x y轴上各取n个点的平均值就是最小值

    至于在不在m边形里,判断一下吧

    不在里面就在线上,m条边求下导,求出最小值的位置

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <time.h>
    #include <vector>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <set>
    #include <vector>
    using namespace std;
    template <class T>
    inline bool rd(T &ret) {
        char c; int sgn;
        if (c = getchar(), c == EOF) return 0;
        while (c != '-' && (c<'0' || c>'9')) c = getchar();
        sgn = (c == '-') ? -1 : 1;
        ret = (c == '-') ? 0 : (c - '0');
        while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return 1;
    }
    template <class T>
    inline void pt(T x) {
        if (x <0) {
            putchar('-');
            x = -x;
        }
        if (x>9) pt(x / 10);
        putchar(x % 10 + '0');
    }
    typedef long long ll;
    typedef pair<int, int> pii;
    const int N = 1e5+10;
    const int inf = 1e9;
    const double eps = 1e-4;
    struct Point{
        double x, y;
        Point(double a = 0, double b = 0) :x(a), y(b){}
    }a[N], b[N];
    int n, m;
    double cx, cy, C;
    double good_x, good_y;
    double cal(double x, double y){
        double ans = 0;
        for (int i = 0; i < n; i++)
            ans += (a[i].x - x)*(a[i].x - x) + (a[i].y - y)*(a[i].y - y);
        return ans;
    }
    double area(Point x, Point y, Point z){
        return abs(x.x*y.y  + y.x*z.y + z.x*x.y - x.x*z.y - y.x*x.y - z.x*y.y) / 2.0;
    }
    double work(Point x){
        double ans = 0;
        for (int i = 0; i < m; i++)
            ans += area(x, b[i], b[(i + 1) % m]);
        return ans;
    }
    double papa(Point x){
        return n*x.x*x.x + n*x.y*x.y - 2 * x.x*cx - 2 * x.y*cy;
    }
    Point cut(Point x, Point y, double k){
        return Point(x.x + k*(y.x - x.x), x.y + k*(y.y - x.y));
    }
    double hehe(Point x, Point y){
        double ans = min(papa(x), papa(y));
        if (y.x != x.x){
            double k = (y.y - x.y) / (y.x - x.x), b = x.y - k*x.x;
            double _x = (k*cy + cx - n*k*b) / n / (1 + k*k);
            if (_x < min(x.x, y.x) || _x > max(x.x, y.x))return ans;
            double _y = k*_x + b;
            ans = min(ans, papa(Point(_x, _y)));
        }
        else {
            if (min(x.y, y.y) <= good_y && good_y <= max(x.y, y.y))
                ans = min(ans, papa(Point(x.x, good_y)));
        }
        return ans;
    }
    int main(){
        rd(n);
        cx = cy = C = 0;
        for (int i = 0; i < n; i++){
            rd(a[i].x), rd(a[i].y);
            cx += a[i].x;
            cy += a[i].y;
            C += a[i].x*a[i].x + a[i].y*a[i].y;
        }
        rd(m);
        for (int i = 0; i < m; i++)rd(b[i].x), rd(b[i].y);
        good_x = (double)cx / n;
        good_y = (double)cy / n;
        if (abs(work(b[0]) - work(Point(good_x, good_y))) < eps) 
            printf("%.10f
    ", cal(good_x, good_y));
        else {
            double ans = 1e19;
            for (int i = 0; i < m; i++)
                ans = min(ans, hehe(b[i], b[(1 + i) % m]));
            printf("%.10f
    ", ans + C);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    void及void指针含义的深刻解析
    对个人站长职业前景的探讨之路在何方?
    Swift编程语言学习4.3—— 控制语句
    二分查找
    分布式文件系统
    常见浏览器兼容性问题与解决方式
    OutputDebugString()
    眼睛的颜色
    SVM-支持向量机算法概述
    Android学习笔记(四十):Preference的使用
  • 原文地址:https://www.cnblogs.com/dgutfly/p/5925047.html
Copyright © 2011-2022 走看看