SCU2016-02 P题 (凸包)

本文介绍了一种计算二维平面上一系列点构成的凸包周长的算法实现。通过先排序点集,再利用极角排序及交叉乘积确定凸包上的点,最终计算出凸包周长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分析:

内部图案虽然可以凹下去,但是外壳是凸的,这样就才会更节省材料,然后发现就是求凸包周长即可。

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define pr(x) cout << #x << ": " << x << "  " 
#define pl(x) cout << #x << ": " << x << endl;

struct point 
{
    int x,y,n;
}dian[1010],stk[1010];
int n;

int dis(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}//返回的是距离的平方
int cross(point p,point s,point e)
{
    return (e.x-s.x)*(p.y-s.y)-(p.x-s.x)*(e.y-s.y);
}
int cmp1(const void *a,const void *b)//将点按y值从小到大x值从小到大排序,找出左下角的点
{
    point *c=(point*)a,*d=(point*)b;
    if(c->y==d->y)
        return c->x-d->x;
    return c->y-d->y;
}
int cmp2(const void *a,const void *b)//按极角从小到大排序
{
    int ret;
    point *c=(point*)a,*d=(point*)b;
    ret=cross(*d,dian[0],*c);
    if(ret!=0) return -ret;
    else if(dis(*c,dian[0])>dis(*d,dian[0]))
        return 1;
    else return 0;
}
int tubao(point dian[],point stk[],int n)//输入的点  输出的点 输入点的个数(下标从0开始) 返回凸包上点的个数
{
    int i,top=1;
    qsort(dian,n,sizeof(dian[0]),cmp1);
    qsort(dian+1,n-1,sizeof(dian[1]),cmp2);
    stk[0]=dian[0];
    stk[1]=dian[1];
    //stk[2]=dian[2];
    for(i=2;i<n;++i)
    {
        while(top>0&&cross(dian[i],stk[top-1],stk[top])<=0) --top;
        stk[++top]=dian[i];
    }
    return top+1;
}
int main()
{
    int l,i;
    double ret,a;
    while(scanf("%d%d",&n,&l)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%d%d",&dian[i].x,&dian[i].y);
        n=tubao(dian,stk,n);
        ret=3.1415926*l*2;
        for(i=0;i<n;i++)
        {
            l=dis(stk[i],stk[(i+1)%n]);
            a=sqrt((double)l);
            ret+=a;
        }
        printf("%.0f\n",ret);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值