USACO 5.1.1凸包

转自:http://blog.csdn.net/cnyali/article/details/50097593

程序:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;

typedef struct
{
	double x,y;
}P;
typedef struct
{
	int s,t;
	double k,l;
}E;

int n,top;
double sum;
P p[10010];
E e[20020];

bool comp(const P &a,const P &b)
{
	return a.x<b.x;
}

double dist(int a,int b)
{
	return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}

double slope(int a,int b)
{
	if (p[b].x-p[a].x==0) return 0;
	return (p[b].y-p[a].y)*1.0/(p[b].x-p[a].x);
}

int main()
{
	freopen("fc.in","r",stdin);
	freopen("fc.out","w",stdout);
	int i,j;
	scanf("%d",&n);
	for (i=1;i<=n;i++)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	sort (p+1,p+n+1,comp);
	i=1;
	while (i<n) {
		j=i+1;
		e[++top].s=i;
		e[top].t=j;
		e[top].l=dist(i,j);
		e[top].k=slope(i,j);
		while (top>1&&e[top-1].k>e[top].k) {
			top--;
			e[top].t=e[top+1].t;
			e[top].l=dist(e[top].s,e[top].t);
			e[top].k=slope(e[top].s,e[top].t);
		}
		i++;
	}
	while (top>0) sum+=e[top--].l;
	i=1;
	while (i<n) {
		j=i+1;
		e[++top].s=i;
		e[top].t=j;
		e[top].l=dist(i,j);
		e[top].k=slope(i,j);
		while (top>1&&e[top-1].k<e[top].k) {
			top--;
			e[top].t=e[top+1].t;
			e[top].l=dist(e[top].s,e[top].t);
			e[top].k=slope(e[top].s,e[top].t);
		}
		i++;
	}
	while (top>0) sum+=e[top--].l;
	printf("%.2f\n",sum);
	return 0;
}
时间: 2024-12-14 08:40:58

USACO 5.1.1凸包的相关文章

【COGS &amp; USACO】896. 圈奶牛(凸包)

http://cojs.tk/cogs/problem/problem.php?pid=896 我的计算几何入门题... 看了看白书的计算几何部分,,恩好嘛.. 乃们都用向量!!!! 干嘛非要将2个点确定一条线变成一个点从原点o出发的射线!!!! 这就是所谓的玩概念吗 然后用所谓的向量加减,是这些向量起点相同,然后就变成了原点o出发的射线!!! 然后你们还在玩概念!我跪了. (以上纯属蒟蒻吐槽) 好吧,计算几何非常有用的..简化了不少操作. 这里还有啥点积啥叉积.点积就是同一起点的向量(终点)的

USACO Section 5.1 Fencing the Cows(凸包)

裸的凸包..很好写,废话不说,直接贴代码. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #define rep(i,r) for(int i=0;i<r;i++) using namespace std; const int maxn=10000+5; struct P { double x,y; P(do

COGS 696. [IOI1996][USACO 2.3] 最长前缀

★   输入文件:prefix.in   输出文件:prefix.out   简单对比时间限制:1 s   内存限制:128 MB 描述 USACO 2.3.1 IOI96 在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的.生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣. 如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素.元素不一定要全部出现(如下例中B

POJ3528 HDU3662 三维凸包模板

POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四面体内,为了让它进入凸包, 则对于所有凸包上的边,若边的一面是该点可以看到的而另一面看不到,则该点与该边构成的面要加入凸包. 模板代码非常清晰, #include<stdio.h> #include<algorithm> #include<string.h> #includ

关于2016.12.12——T1的反思:凸包的意义与应用

2016.12.12 T1 给n个圆,保证圆圆相离,求将圆围起来的最小周长.n<=100 就像上图.考场上,我就想用切线的角度来做凸包.以圆心x,y排序,像点凸包一样,不过用两圆之间的下切线角度来判断. 这就是下切线(我自己瞎编的名字): 好像是对的啊: 然后我就保证必AC的希望,用这种写法交了,然后就只得了N=2的暴力分... 自以为是正解,却落得如此下场... 为什么?这样不对吗?借用学长的力量,果然被Hack掉了: 这种情况,圆心排序后,检测的顺序并不是圆上的切点的顺序,自然就会挂. 蓝瘦

poj 1113 凸包周长

Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33888   Accepted: 11544 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he w

UVA 11800 Determine the Shape --凸包第一题

题意: 给四个点,判断四边形的形状.可能是正方形,矩形,菱形,平行四边形,梯形或普通四边形. 解法: 开始还在纠结怎么将四个点按序排好,如果直接处理的话,有点麻烦,原来凸包就可搞,直接求个凸包,然后点就自动按逆时针排好了,然后就判断就可以了,判断依据题目下面有,主要是用到点积和叉积,判断垂直用点积,判断平行用叉积. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstd

POJ 3348 最直接的凸包问题

题目大意: 给定一堆树的点,找到能组合成的最大面积,一个物体占50面积,求最多放多少物体 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const double eps = 1e-10; 7 const int N = 10005; 8 double myabs(double x) 9

hdu 1348 Wall(凸包模板题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3386    Accepted Submission(s): 968 Problem Description Once upon a time there was a gre