Junior high school math

The meaning of problems

Initially only a plane containing three points, and then will appear one of the N points. Each add a point, you find the perimeter of a polygon containing a minimum area of ​​these points.


Thinking

Maintain a balanced tree, look for each insertion predecessor and successor, then you can add nodes.

Note that this problem is likely the case collinear appears, you can specify the initial point by random to resolve.

Accuracy slightly at the cancer.

Code

#include <bits/stdc++.h>
#include <cmath>

using namespace std;

namespace StandardIO {

    template<typename T> inline void read (T &x) {
        x=0;T f=1;char c=getchar();
        for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
        for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
        x*=f;
    }
    template<typename T> inline void write (T x) {
        if (x<0) putchar('-'),x=-x;
        if (x>=10) write(x/10);
        putchar(x%10+'0');
    }

}

using namespace StandardIO;

namespace Solve {
    
    const int N=100100;
    
    int n;
    long long ans;
    struct node {
        long long x,y;
        long double rad;
        node () {}
        node (int _x,int _y):x(_x),y(_y){}
        node (int _x,int _y,long double _r):x(_x),y(_y),rad(_r){}
        node operator - (const node &a) {
            return node(x-a.x,y-a.y);
        }
        node operator + (const node &a) {
            return node(x+a.x,y+a.y);
        } 
        long long operator * (const node &a) {
            return (x*a.y-y*a.x);
        }
    } a[N],S;
    long double X,Y;
    set<node> sexy;
    
    inline bool operator < (const node &x,const node &b) {
        return x.rad<b.rad;
    }
    inline long double rad (node x) {
        return (long double)atan2((x.y-S.y),(x.x-S.x));
    }
    inline node pre (node x) {
        if (sexy.count(x)) return x;
        set<node>::iterator it=sexy.lower_bound(x);
        if (it==sexy.begin()) it=sexy.end();
        return *(--it);
    }
    inline node suc (node x) {
        set<node>::iterator it=sexy.upper_bound(x);
        if (it==sexy.end()) it=sexy.begin();
        return *it;
    }
    inline long long Abs (long long a) {
        return (a>0)?a:-a;
    }
    inline long long calc (node x,node b) {
        return Abs(x*b);
    }
    inline void insert (node x) {
        if (sexy.size()<=2) {
            sexy.insert(x);
            return;
        }
        node l=pre(x),r=suc(x);
        if ((x-l)*(r-l)<=0) return;
        ans+=calc(x-l,r-l);
        while (1) {
            node tmp=pre(x);
            sexy.erase(tmp),l=pre(x);
            if ((x-l)*(l-tmp)>=0) {
                sexy.insert(tmp);
                break;
            }
            ans+=calc(tmp-x,l-x);
        }
        while (1) {
            node tmp=suc(x);
            sexy.erase(tmp),r=suc(x);
            if ((x-r)*(r-tmp)<=0) {
                sexy.insert(tmp);
                break;
            }
            ans+=calc(tmp-x,r-x);
        }
        sexy.insert(x);
    }
    inline void init () {
        long double J=(long double)1.92,Z=(long double)6.08,M=(long double)1.7;
        S=node((long double)((long double)a[1].x*J+(long double)a[2].x*Z+(long double)a[3].x*M)/(long double)(J+Z+M),(long double)((long double)a[1].y*J+(long double)a[2].y*Z+(long double)a[3].y*M)/(long double)(J+Z+M));
        insert(node(a[1].x,a[1].y,rad(a[1])));
        insert(node(a[2].x,a[2].y,rad(a[2])));
        insert(node(a[3].x,a[3].y,rad(a[3])));
        ans+=calc(a[1]-a[3],a[3]-a[2]);
    }

    inline void MAIN () {
        for (register int i=1; i<=3; ++i) read(a[i].x),read(a[i].y);
        init();
        read(n);
        for (register int i=4; i<=n+3; ++i) {
            read(a[i].x),read(a[i].y);
            insert(node(a[i].x,a[i].y,rad(a[i])));
            write(ans),putchar('\n');
        }
    }
    
    #undef int
}

int main () {
    Solve::MAIN();
}

Guess you like

Origin www.cnblogs.com/ilverene/p/11357341.html