hdu1392(凸包模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392

思路:求凸包周长,很明显的模板题。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <unordered_map>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define mod int(1e9+7)
#define pb push_back
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
#define eps 1e-8
int n,top,m,cnt;
double x,y;
const int N=108;
struct point
{
    double x,y;
    point(){}
    point(double a,double b):x(a),y(b){}
    point operator-(point a){//向量减法
        return point(x-a.x,y-a.y);
    }
    point operator+(point a){//向量加法
        return point(x+a.x,y+a.y);
    }
    double operator*(point a){//向量叉积
        return x*a.y-y*a.x;
    }
    bool operator<(const point a) const{
        if(fabs(x-a.x)<eps) return y<a.y;
        return x<a.x;
    }
    double len(){//向量模的平方
        return sqrt(x*x+y*y);
    }
}a[N],p[N];
double cj(point a,point b,point c) {return (a-c)*(b-c);}//定义叉积
void graham()
{
    sort(a+1,a+cnt+1);//将点按x坐标排序,x坐标相同就按y坐标排序
    p[1]=a[1],p[2]=a[2],top=2;
    for(int i=3;i<=cnt;i++)//从前往后扫
    {
        while(top>1&&cj(a[i],p[top],p[top-1])>=0) top--;
        p[++top]=a[i];
    }
    m=top;
    p[++top]=a[cnt-1];
    for(int i=cnt-2;i>=1;i--)//从后往前扫
    {
        while(top>m&&cj(a[i],p[top],p[top-1])>=0) top--;
        p[++top]=a[i];
    }
}
int main()
{
    cin.tie(0);
    cout.tie(0);
    while(cin>>n&&n)
    {
        FOR(i,1,n) sd(a[i].x),sd(a[i].y);
        sort(a+1,a+n+1);
        cnt=1;
        FOR(i,2,n)
        {
            if(fabs(a[i].x-a[cnt].x)>eps||fabs(a[i].y-a[cnt].y)>eps) a[++cnt]=a[i];
        }//去除相同点
        if(cnt==1) {puts("0.00");continue;}
        if(cnt==2) {printf("%.2lf\n",(a[2]-a[1]).len());continue;}
        graham();
        double ans=0.0;
        p[top]=p[1];//不写也行,头和尾其实是一样的
        FOR(i,1,top-1) ans+=(p[i]-p[i+1]).len();
        printf("%.2lf\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40858062/article/details/81303414