C题Dogs'House 求凸包上的点
来源:互联网 发布:沈阳盘古网络工资 编辑:程序博客网 时间:2024/04/27 02:42
C-Dogs' House
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 134 Accepted Submission(s) : 45
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
George wishes to build a House to contain his dogs(without roof), but he's a bit short on cash right. Any Wall he builds must contain all of the favorite grazing spots for his dogs. Given the location of these spots, determine the length of the shortest Wall which encloses them.
Input
There are several test cases.
In each test case:
The first line of the input file contains one integer, N. N (0 <= N <= 10,000) is the number of grazing spots that George wishes to enclose. The next N line consists of two real numbers, Xi and Yi, corresp
onding to the location of the grazing spots in the plane (-1,000,000 <= Xi,Yi <= 1,000,000). The numbers will be in decimal format.
In each test case:
The first line of the input file contains one integer, N. N (0 <= N <= 10,000) is the number of grazing spots that George wishes to enclose. The next N line consists of two real numbers, Xi and Yi, corresp
onding to the location of the grazing spots in the plane (-1,000,000 <= Xi,Yi <= 1,000,000). The numbers will be in decimal format.
Output
The output should consist of one real number, the length of fence required. The output should be accurate to two decimal places.
Sample Input
44 84 125 9.37 8
Sample Output
12.00
Author
给出一系列的点 围城一个凸多边形,使其包括所有的点,求这个凸多边形的周长。
采用的是思路比较简单的卷包裹法
先找出所有点中最左边的点,然后求最左边上的点与图中每一个点的sin值,将sin值按从小到大的顺序排放,如果点是从0位置开始排序的话,那么0,1必是凸包上面的点,一遍从最左边扫到最右边,求cross(叉积)值,确定每条边所拐的方向是否为同一个方向,(用stl函数库定义两个栈,一个存放向量,另一个存放点,)如果是一个方向,向量和点进栈,如果不是一个方向,向量和点出栈 。 求得向量栈中的所有向量的长度,这里包括起始点和终点所连的向量。
#include<stdio.h>#include<iostream>#include<algorithm>#include<math.h>#include<stack>struct stu { //定义了两个向量 double x,y; }vec[2]; struct node{ //定义了每个点的四种属性 角度,两点距离,横纵坐标 double x,y,sinangle,dis; }point[20000]; int cmp(node a,node b) //比较函数 快排的比较函数确定最左边的坐标 { if(b.x-a.x>0)return 1; else return 0; }int cmp1(node a,node b)//按sinangle的角度大小 从小到大进行排序 { if(b.sinangle-a.sinangle>0) return 1; else return 0;}double judge(stu a,stu b)// 向量的叉积 { if( a.x*b.y-a.y*b.x>0)return 100; else return -100; }double distant(node a,node b){ return sqrt( (b.y-a.y)*(b.y-a.y)+(b.x-a.x)*(b.x-a.x) ); }double value(stu a){ return sqrt( a.x*a.x+a.y*a.y ); }const double min=0.0000001; //定义了最小值 using namespace std;stack <struct stu> my; stack <struct node> doc; int main(){ int n,i; node j; stu num; double sum=0; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++) //输入n组数据 scanf("%lf %lf",&point[i].x,&point[i].y); sort(point,point+n,cmp); //对其进行排序找出最左边的值 //输出所有数据 // for(i=0;i<n;i++) // printf("%lf %lf\n",point[i].x,point[i].y); //找出最小值 // printf("min x %lf %lf",point[0].x,point[0].y); for(i=1;i<n;i++) { point[i].dis=distant(point[0],point[i]); point[i].sinangle=(point[i].y-point[0].y)/point[i].dis; // printf("point[%d].sinangle=%lf\n",i,point[i].sinangle); } // printf("\n"); sort(point+1,point+n,cmp1);//按角度进行排序(从小到大) //输出从1-n-1的sinangle值 // for(i=1;i<n;i++) // printf("point[%d].sinangle=%lf\n",i,point[i].sinangle); // printf("!!!!!!!!!!!!!!!\n"); vec[0].x=point[1].x-point[0].x; //第一条边一定产生是凸包的一条边 vec[0].y=point[1].y-point[0].y; while(!my.empty()) my.pop(); //my栈中存放的是向量的值 my.push(vec[0]); //将栈中原来的所有点释放 while(!doc.empty()) //doc栈中存放的点 doc.pop(); doc.push(point[0]); //0,1两个点必在凸包中。 doc.push(point[1]); point[n]=point[0]; //将point[0]赋给point[n]形成一个循环 for(i=2;i<=n;i++) { //printf("i=%d\n",i); vec[0]=my.top(); j=doc.top(); vec[1].x=point[i].x-j.x; //反复使用vec[0],vec[1]生成向量 vec[1].y=point[i].y-j.y; if(judge(vec[0],vec[1])>0){ //如果旋转方向相同 点和向量进栈 doc.push(point[i]); my.push(vec[1]); } else {my.pop();doc.pop();i--;} //如果不相同,则点和向量出栈 } sum=0; while(!my.empty()) { num=my.top(); my.pop(); sum+=value(num); } printf("%.2lf\n",sum); }}
- C题Dogs'House 求凸包上的点
- 输出凸包上的所有点
- 求凸包上最远两点距离的平方值
- 求凸包上最大距离 poj2187
- 算法:分治法求凸包上的点以及由凸包所构成的多边形的面积
- poj2187 凸包上的最远点对的距离(凸包+旋转卡壳)
- C-Dogs for ios
- poj 2187 凸包上的直径 - 旋转卡壳
- UVA 10078 The Art Gallery【输入点是否全部在凸包上】
- Watch dogs的CTOS
- POJ 2761 Feed the dogs 树状数组求第k大的数
- poj 2761 Feed the dogs 求区间第k大的数
- POJ 2761-Feed the dogs(划分树)求区间内第k小的数
- 求点A绕点B转到点C转过的角度
- 求连通图的关节点(割点)--C语言
- 【Codeforces Round 335 (Div 2)E】【计算几何-凸包 线性规划 三分凸包上最优点】Freelancer's Dreams 二维属性 充最少的钱变得满足要求 [计算几何-凸包模
- 当点C在抛物线上移动时,求点P的轨迹方程
- hdoj 5538 House Building 【正反扫 求表面积 简单题】
- 软件开发中常见的开源协议
- linux jdk 设置
- LINQ多条件查询
- 字符串的组合
- 去除HTML的正则表达式函数
- C题Dogs'House 求凸包上的点
- 捕获异常语句try..catch..finally..
- PHP绘制花边广告展示条
- poj2186 - Popular Cows
- 获取程序运行后的html源码
- MVC知识点总结
- 我的核心竞争力在哪里?
- asp.net的编译
- IIS下的URL重写无效问题