andrew算法

#include <cstdio>
#include <algorithm>
#define maxn 120005
#define eps 1e-8
using namespace std;
int n;
struct point{
    double x, y;
    point(){}
    point(double a, double b):x(a),y(b){}
    point operator - (const point &b) const
    {
        return  point(x-b.x, y-b.y);
    }
    bool operator < (const point &b) const
    {
        return x<b.x||(x == b.x && y < b.y);
    }

}p[maxn], res[maxn], pb[maxn];
int dcmp(double x){
    return (x>eps) - (x < -eps);
}
double cross(point a, point b){
    return a.x*b.y-b.x*a.y;
}
int andrew(){
    sort(p, p+n);
    int m = 0, i;
    for(i = 0; i < n; i++){
        while(m>1 && cross(res[m-1]-res[m-2], p[i]-res[m-2]) < 0)
            m--;
        res[m++] = p[i];
    }
    int k = m;
    for(i = n-2 ; i >= 0; i--){
        while(m>k && cross(res[m-1]-res[m-2], p[i]-res[m-2]) < 0)
            m--;
        res[m++] = p[i];
    }
    if(m>1) m--;
    return m;
}
int main(){
    int na, nb, i;
    scanf("%d", &na, &nb);
    for(i = 0; i < na; i++){
        scanf("%lf %lf", &p[i].x, &p[i].y);
    }
    scanf("%d", &nb);
    n = na+nb;
    for(i = na; i < n; i++){
        scanf("%lf %lf", &p[i].x, &p[i].y);
        pb[i-na] = p[i];
    }
    int m = andrew();
    sort(pb, pb+nb);
    int tmp;
    int flag = 1;
    for(i = 0; i < m; i++){
        tmp = lower_bound(pb, pb+nb, res[i]) - pb;
        if(dcmp(pb[tmp].x - res[i].x) == 0 && dcmp(pb[tmp].y - res[i].y)== 0)
        {
            flag = 0;
            break;
        }
    }
    if(flag) printf("YES");
    else printf("NO");
    return 0;
}

求凸包面积

double area(int m){
    double ans = 0;
    int i;
    for(i = 1; i < m-1; i++)
        ans += cross(res[i]-res[0], res[i+1]-res[0]);
    return fabs(ans/2);
}

求凸包周长

double length(int m){
    double ans = 0;
    int i;
    for(i = 0; i < m; i++)
        ans += dist(res[i], res[(i+1)%m]);
    return ans;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值