【凸包构造】poj 1113 Wall

poj 1113 Wall

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

问题描述:凸包长度

问题答案是凸包的长度+以l为半径的圆周长(围墙是一个圆角多边形,圆周的那部分之和为一个圆)

http://blog.csdn.net/zhengnanlee/article/details/9633357

思路

凸包构造+遍历求周长+圆周长


参考代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<algorithm>
#include<set>
#include<sstream>
#define eps 1e-9
#define pi acos(-1)
using namespace std;

typedef long long ll;

const int _max = 1e3 + 10;

int n,l;

int dcmp(double x){
  if(fabs(x)<eps) return 0;else return x < 0?-1:1;
}

struct point{
  double x,y;
}p[_max],res[_max];

bool mult(point sp,point ep,point op){
  return (sp.x - op.x) * (ep.y - op.y)
       >= (ep.x - op.x) * (sp.y - op.y);
}

bool operator < (const point &l, const point &r){
   return l.y < r.y ||(l.y == r.y && l.x < r.x);
}

double len(point a,point b){
  return hypot(b.x-a.x,b.y-a.y);
}

int graham(point pnt[],int n, point res[]){//构造凸包
  int i,len ,k = 0,top = 1;
  sort(pnt,pnt+n);
  if(n == 0)return 0; res[0] = pnt[0];
  if(n == 1)return 1; res[1] = pnt[1];
  if(n == 2)return 2; res[2] = pnt[2];
  for(int i =2; i < n; ++ i){
    while(top && mult(pnt[i],res[top],res[top-1]))
        top--;
    res[++top] = pnt[i];
  }
  len = top; res[++top] = pnt[n - 2];
  for(i = n - 3; i >= 0; -- i){
    while(top!=len && mult(pnt[i],res[top],res[top-1]))
        top--;
    res[++top] = pnt[i];
  }
  return top;//返回凸包中点的个数
}

int main(){
 #ifndef ONLINE_JUDGE
 freopen("input.txt","r",stdin);
 #endif // ONLINE_JUDGE
 while(scanf("%d%d",&n,&l) == 2){
    for(int i = 0; i < n; ++ i)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    n = graham(p,n,res);
    double tar = 2 * pi * l; //圆的周长+凸包的周长
    for(int i = 0; i < n; ++ i)
        tar+=len(res[i],res[(i+1)%n]);
    printf("%.0f\n",tar);//四舍五入
 }
 return 0;
}
  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值