UVALive 6859 Points (凸包)

Points

題目連接:

http://acm.hust.edu.cn/vjudge/contest/130303#problem/Eios

Description


http://7xjob4.com1.z0.glb.clouddn.com/4c9abc79e61f4d543441b48cb0cf6bbe
less

Input


The input file contains several test cases, each of them as described below.
The first line contains integer N — the number of points placed by Peter (1 ≤ N ≤ 100000). Each of
following N lines contains two integers xi , yi — the point coordinates placed by Peter. The coordinates by absolute value do not exceed 10^6 . Some points can match.
ui

Output


For each test case, you need to print one number — the perimeter of the required polygon, on a line
by itself. The answer should be printed with accuracy not less than 0.001.
spa

Sample Input

1
0 0
2
1 1
1 2

Sample Output

5.656
7.656854

Source


2016-HUST-線下組隊賽-4
code


題意:


給出網格上的n個點,求一個周長最小的多邊形使得全部點都在其內部,且多邊形的邊要麼是網格的邊,要麼是網格的對角線.
ip


題解:


因爲邊只能是網格邊或者對角線,在紙上畫一下三角形時的狀況便可推出結果輪廓.
先對全部點求一個凸包,而後把凸包拓展成爲由網格邊或對角線組成的多邊形,再總體往外擴大1便是最後的結果.
get


代碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define LL long long
#define maxn 111000
#define inf 0x3f3f3f3f
#define mod 1000000007
#define mid(a,b) ((a+b)>>1)
#define eps 1e-8
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n;
struct Point{
    LL x,y;
    Point() {}
    Point(LL tx, LL ty) {x=tx;y=ty;}
}p[maxn];

LL xmul(Point p0, Point p1, Point p2) {
    return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);
}

LL Dis(Point p1, Point p2) {
    return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
}

int s[maxn], top;
int cmp_polar(Point p1, Point p2) {
    LL tmp = xmul(p[0], p1, p2);
    if(tmp > 0) return 1;
    else if(tmp==0 && (Dis(p[0],p1)-Dis(p[0],p2))<0) return 1;
    else return 0;
}

void polar(int n) {
    int pos = 0;
    Point p0 = p[0];
    for(int i=1; i<n; i++) {
        if(p0.y>p[i].y || (p0.y==p[i].y && p0.x>p[i].x)) {
            p0 = p[i];
            pos = i;
        }
    }
    p[pos] = p[0];
    p[0] = p0;

    sort(p+1, p+n, cmp_polar);
}

void Gramham(int n) {
    polar(n);

    top = 0;
    for(int i=0; i<n; i++) {
        while(top>1 && xmul(p[s[top-2]],p[s[top-1]],p[i])<=0) top--;
        s[top++] = i;
    }
}

int main()
{
    //IN;

    while (scanf("%d", &n) != EOF)
    {
        for(int i=0; i<n; i++) {
            scanf("%I64d %I64d", &p[i].x, &p[i].y);
        }

        Gramham(n);

        LL ans1 = 0, ans2 = 0;
        for(int i=0; i<top; i++) {
            Point p1, p2;
            p1 = p[s[i]];
            if(i<top-1) p2 = p[s[i+1]];
            else p2 = p[s[0]];

            LL dx = abs(p1.x - p2.x);
            LL dy = abs(p1.y - p2.y);
            ans1 += abs(dx - dy);
            ans2 += min(dx, dy);
        }

        ans2 += 4;
        double ans = 1.0*ans1 + sqrt(2.0)*(double)ans2;

        printf("%f\n", ans);
    }

    return 0;
}
相關文章
相關標籤/搜索