hdu1392 Surround the Trees 【简单凸包】

题意:

给你n个点,求将所有点都围起来的凸包的周长

题目链接:传送门

关于凸包的原理:传送门

AC_code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 1e5 + 10, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;

struct Point {
	double x, y;
	Point (double x = 0, double y = 0):x(x),y(y) {}
	Point operator + (const Point &b) {
		return Point(x+b.x, y+b.y);
	}
	Point operator - (const Point &b) {
		return Point(x-b.x,y-b.y);
	}
} p[N],res[N];

double dis(Point aa, Point bb) {
	return sqrt((aa.x - bb.x) * (aa.x - bb.x) + (aa.y - bb.y) * (aa.y - bb.y));
}
double dot(Point aa, Point bb) {
	return aa.x * bb.y - bb.x * aa.y;
}
bool cmp(Point aa, Point bb) {
	if(aa.y == bb.y) {
		return aa.x < bb.x;
	} else {
		return aa.y < bb.y;
	}
}

int get(Point* p, int n, Point* res) {
	sort(p+1, p+1+n, cmp);
	res[1] = p[1];
	res[2] = p[2];
	int top = 2, len;
	for(int i = 3; i <= n; i++) {
		while(top >= 2 && dot((p[i] - res[top - 1]), (res[top] - res[top-1])) >= 0) {
			top--;
		}
		res[++top] = p[i];
	}
	len = top;
	for(int i = n; i >= 1; i--) {
		while(top != len && dot((p[i] - res[top - 1]), (res[top] - res[top-1])) >= 0) {
			top--;
		}
		res[++top] = p[i];
	}
	return top;
}


int main() {
	int n;
	while(~scanf("%d", &n)) {
		if(n == 0) {
			break;
		}
		for(int i = 1; i <= n; i++) {
			scanf("%lf%lf", &p[i].x, &p[i].y);
		}
		if(n == 1) {
			printf("0.00\n");
			continue;
		} else if(n == 2) {
			printf("%.2lf\n",dis(p[1], p[2]));
			continue;
		}

		int m = get(p, n, res);
		double tot = 0;
		for(int i = 2; i <= m ; i++) {
			tot += dis(res[i-1], res[i]);
		}
		printf("%.2lf\n", tot);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值