hdu 1348(凸包)

Wall

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4903    Accepted Submission(s): 1419

Problem Description

Once
upon a time there was a greedy King who ordered his chief Architect to
build a wall around the King‘s castle. The King was so greedy, that he
would not listen to his Architect‘s proposals to build a beautiful brick
wall with a perfect shape and nice tall towers. Instead, he ordered to
build the wall around the whole castle using the least amount of stone
and labor, but demanded that the wall should not come closer to the
castle than a certain distance. If the King finds that the Architect has
used more resources to build the wall than it was absolutely necessary
to satisfy those requirements, then the Architect will loose his head.
Moreover, he demanded Architect to introduce at once a plan of the wall
listing the exact amount of resources that are needed to build the wall.
Your
task is to help poor Architect to save his head, by writing a program
that will find the minimum possible length of the wall that he could
build around the castle to satisfy King‘s requirements.

The
task is somewhat simplified by the fact, that the King‘s castle has a
polygonal shape and is situated on a flat ground. The Architect has
already established a Cartesian coordinate system and has precisely
measured the coordinates of all castle‘s vertices in feet.

Input

The
first line of the input file contains two integer numbers N and L
separated by a space. N (3 <= N <= 1000) is the number of vertices
in the King‘s castle, and L (1 <= L <= 1000) is the minimal
number of feet that King allows for the wall to come close to the
castle.

Next N lines describe coordinates of castle‘s vertices in
a clockwise order. Each line contains two integer numbers Xi and Yi
separated by a space (-10000 <= Xi, Yi <= 10000) that represent
the coordinates of ith vertex. All vertices are different and the sides
of the castle do not intersect anywhere except for vertices.

Output

Write
to the output file the single number that represents the minimal
possible length of the wall in feet that could be built around the
castle to satisfy King‘s requirements. You must present the integer
number of feet to the King, because the floating numbers are not
invented yet. However, you must round the result in such a way, that it
is accurate to 8 inches (1 foot is equal to 12 inches), since the King
will not tolerate larger error in the estimates.

This problem contains multiple test cases!

The
first line of a multiple input is an integer N, then a blank line
followed by N input blocks. Each input block is in the format indicated
in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

Sample Input

1

9 100
200 400
300 400
300 300
400 300
400 400
500 400
500 200
350 200
200 200

Sample Output

1628

Source

Northeastern Europe 2001

题意:国王要在城堡外修一个外墙,这一个外墙要隔城堡至少m英尺,求修这个外墙需要的最小费用
分析:我们先要找到刚好囊括整个城堡的一个外墙,这里要利用凸包算法,然后加上一个圆的周长,这里利用的是Graham算法。下面是算法流程:

令p0为Q中Y-X(not X-Y)坐标排序下最小的点
 设<p1,p2,...pm>为对其余点按以p0为中心的极角逆时针排序所得的点集(如果有多个点有相同的极角,除了距p0最远的点外全部移除
 压p0进栈S
 压p1进栈S
 压p2进栈S
  for i ← 3 to m
  do while 由S的栈顶元素的下一个元素、S的栈顶元素以及pi构成的折线段不拐向左侧
      对S弹栈
      压pi进栈S
  return S;

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int N = 1005;
const double pi = atan(1.0)*4;
const double eps = 1e-8;
struct Point
{
    double x,y;
} p[N];
Point Stack[N]; ///模拟栈,不然的话取到栈的第二个元素不好处理
double mult(Point a,Point b,Point c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
double dis(Point a,Point b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int n,m;
int cmp(Point a,Point b)  ///设<p1,p2,...pm>为对其余点按以p0为中心的极角逆时针排序所得的点集(如果有多个点有相同的极角,除了距p0最远的点外全部移除)
{
    if(mult(a,b,p[0])>0)
        return 1;
    if(mult(a,b,p[0])==0&&dis(b,p[0])-dis(a,p[0])>eps)
        return 1;
    return 0;
}
int Graham()
{
    int top=2; ///栈顶在2,因为凸包的前两个点是不会变了
    sort(p+1,p+n,cmp);
    Stack[0]=p[0];   ///压p0p1p2进栈S
    Stack[1]=p[1];
    Stack[2]=p[2];
    for(int i=3;i<n;i++){
        while(top>=1&&mult(p[i],Stack[top],Stack[top-1])>=0){///有了更好的选择
            top--;
        }
        Stack[++top]=p[i];
    }
    return top;
}
int main()
{
    int tcase;
    scanf("%d",&tcase);
    while(tcase--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        int k = 0;
        for(int i=0; i<n; i++) ///令p0为Q中Y-X坐标排序下最小的点
        {
            if(p[k].y>p[i].y||((p[k].y==p[i].y)&&(p[k].x>p[i].x)))
            {
                k=i;
            }
        }
        swap(p[0],p[k]);
        double sum=0;
        int top = Graham();
        for(int i=1;i<=top;i++){
            sum+=sqrt(dis(Stack[i],Stack[i-1]));
        }
        ///处理最后一个点和P0
        sum+=sqrt(dis(Stack[0],Stack[top]));
        ///加上圆
        sum+=2*pi*m;
        printf("%.0lf\n",sum);
        if(tcase) printf("\n");
    }
    return 0;
}
时间: 2024-08-27 00:04:57

hdu 1348(凸包)的相关文章

hdu 1348 (凸包求周长)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3229    Accepted Submission(s): 919 Problem Description Once upon a time there was a greedy

POJ 1113 || HDU 1348: wall(凸包问题)

传送门: POJ:点击打开链接 HDU:点击打开链接 下面是POJ上的题: Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 29121   Accepted: 9746 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's cast

HDU 4946 凸包

题目大意: 一些点在一张无穷图上面,每个点可以控制一些区域,这个区域满足这个点到达这个区域的时间严格小于其他点.求哪些点能够控制无穷面积的区域. 题目思路: 速度小的控制范围一定有限. 速度最大当且仅当在凸包上才能够控制无穷区域.可以通过,任意两个点中垂线为界,左右各控制一半,判断出凸包内的点仅能控制有限区域. 特判: 速度最大且在同一个点上的点均不能控制无穷区域,但是要加入凸包计算. 速度最大为0不能控制无穷区域. 对于共线凸包(Graham), 1.按极角坐标序排,需要将最后一条边上的点逆序

hdu 1348 Wall(凸包模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3386    Accepted Submission(s): 968 Problem Description Once upon a time there was a gre

hdu 1348 Wall (凸包模板)

/* 题意: 求得n个点的凸包,然后求与凸包相距l的外圈的周长. 答案为n点的凸包周长加上半径为L的圆的周长 */ # include <stdio.h> # include <math.h> # include <string.h> # include <algorithm> using namespace std; # define PI acos(-1.0) struct node { int x; int y; }; node a[1010],res

hdu 1348 Wall (凸包)

Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3139    Accepted Submission(s): 888 Problem Description Once upon a time there was a greedy King who ordered his chief Architect to build a w

HDU 1348 Wall 【凸包】

<题目链接> 题目大意: 给出二维坐标轴上 n 个点,这 n 个点构成了一个城堡,国王想建一堵墙,城墙与城堡之间的距离总不小于一个数 L ,求城墙的最小长度,答案四舍五入. 解题分析: 求出这些点所围成的凸包,然后所围城墙的长度就为 该凸包周长 + 以该距离为半径的圆的周长.具体证明如下: 下面的模板还没有整理好 Graham 凸包算法 #include<iostream> #include<cstdio> #include<cmath> #include&

HDU 1392 凸包

Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10345    Accepted Submission(s): 4009 Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to

POJ 1113&amp;&amp;HDU 1348

题意:凸包周长+一个完整的圆周长.因为走一圈,经过拐点时,所形成的扇形的内角和是360度,故一个完整的圆. 模板题,之前写的Graham模板不对,WR了很多发....POJ上的AC代码 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<set> 6 #include<stdio.h> 7 #inclu