UVALive 6859 Points (凸包)

Points

题目链接:

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

Description

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

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.

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.

Sample Input

``` 1 0 0 2 1 1 1 2 ```

Sample Output

``` 5.656 7.656854 ```

Source

2016-HUST-线下组队赛-4
##题意: 给出网格上的n个点,求一个周长最小的多边形使得所有点都在其内部,且多边形的边要么是网格的边,要么是网格的对角线.
##题解: 由于边只能是网格边或者对角线,在纸上画一下三角形时的情况即可推出结果轮廓. 先对所有点求一个凸包,然后把凸包拓展成为由网格边或对角线组成的多边形,再整体往外扩大1即是最后的结果.
##代码: ``` cpp #include #include #include #include #include #include #include #include #include #include #include #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;

}

posted @ 2016-08-26 17:27  Sunshine_tcf  阅读(230)  评论(0编辑  收藏  举报