欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pku 1113 Wall 凸包

程序员文章站 2022-03-29 21:22:59
...

http://poj.org/problem?id=1113

题意是给定一个城堡的各个点,然你求出设计一个城墙,包围这个城堡并且保证城墙距离城堡必须大于等于一个给定的距离:

首先是利用图报求出最小的包围城堡的凸多边形,然后求出距离,然后再加上一个整圆就OK了,圆的半径就是给定的距离:(整个思路相当于把凸多边形各个边往外移动距离R,此后连接各边的弧组成一个以R为半径的整圆);

到此终于把POJ计划的初级阶段刷完了...纪念一下。。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

const double eps = 1e-8;
const int maxn = 1007;
const double pi = acos(-1.0);
struct point
{
    double x,y;
}pt[maxn],stack[maxn];
int top;

int cmp(point a,point b)
{
    if (a.y != b.y) return a.y < b.y;
    else return a.x < b.x;
}
int dblcmp(double x)
{
    if (x > eps) return 1;
    else if (x < -eps) return -1;
    else return 0;
}
double det(double x1,double y1,double x2,double y2)
{
    return x1*y2 - x2*y1;
}
double cross(point a,point b,point c)
{
    return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
}
//这里起点与终点肯定在凸包上,不知道怎么证明
int graham(point *p,int len)
{
    top = 0;  int i;
    //先排序,lrj黑书上的排序方法
    sort(p,p + len,cmp);
    stack[top++] = p[0];
    stack[top++] = p[1];
    //求右链
    for (i = 2; i < len; ++i)
    {
        while (top > 1 && dblcmp(cross(stack[top - 2],stack[top - 1],p[i])) <= 0) top--;
        stack[top++] = p[i];
    }
    //求左链
    int tmp = top;
    for (i =len - 2; i >= 0; --i)
    {
        while (top > tmp && dblcmp(cross(stack[top - 2],stack[top - 1],p[i]))<= 0) top--;
        stack[top++] = p[i];
    }
    return top - 1;//起点两次进栈 - 1
}
double dis(point a,point b)
{
    double x = a.x - b.x;
    double y = a.y - b.y;
    return sqrt(x*x + y*y);
}
int main()
{
    int n,i,r;
    scanf("%d%d",&n,&r);
    for (i = 0; i < n; ++i) scanf("%lf%lf",&pt[i].x,&pt[i].y);
    int len = graham(pt,n);
    double L = 0;
    for (i = 0; i < len; ++i)
    L += dis(stack[i],stack[(i + 1)%len]);
    L = L + 2.0*pi*r;
    printf("%.0lf\n",L);
    return 0;
}

  

转载于:https://www.cnblogs.com/E-star/archive/2012/06/08/2542123.html

上一篇: testing

下一篇: POJ 1113 Wall(凸包)