Smallest Bounding Rectangle - uva10173
2015-12-05 18:07
351 查看
Smallest Bounding Rectangle
Given the Cartesian coordinates of n(>0)2-dimensional points, write a program that computes the area of their smallest bounding rectangle (smallest rectangle containing all the given points).Input
The input le may contain multiple test cases. Each test case begins with a line containing a positiveinteger n(<1001) indicating the number of points in this test case. Then follows n lines each containing
two real numbers giving respectively the x - and y
-coordinates of a point. The input terminates with a
test case containing a value 0 for n which must not be processed.
Output
For each test case in the input print a line containing the area of the smallest bounding rectanglerounded to the 4th digit after the decimal point.
Sample Input
3-3.000 5.000
7.000 9.000
17.000 5.000
4
10.000 10.000
10.000 20.000
20.000 20.000
20.000 10.000
0
Sample Output
80.0000100.0000
最小外接矩形,不会简单的方法,只能将所给点构成凸包,然后枚举凸包上相邻的两点与x轴的夹角作为矩形的倾斜角c,然后求出沿倾斜角c的方向上的凸包映射的长度和垂直倾斜角c的方向上的映射长度为矩形的长和宽.
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <string> #include <queue> #include <stack> #include <set> #include <vector> #include <map> #include <algorithm> #define LL long long using namespace std; const int INF = 0x3f3f3f3f; const int Max = 1011; const double eps = 1e-8; const double Pi = acos(-1.0); int sgn(double x)//精度处理 { if(fabs(x)<eps) { return 0; } if(x<0) { return -1; } else { return 1; } } struct Point { double x,y; Point() {}; Point(double _x,double _y) { x=_x; y=_y; } Point operator - (const Point &b)const { return Point(x-b.x,y-b.y); } double operator ^ (const Point &b)const { return x*b.y-y*b.x; } double operator * (const Point &b)const { return x*b.x+y*b.y; } void transXY(double B) { double tx = x,ty=y; x =tx*cos(B)-ty*sin(B); y = tx*sin(B)+ty*cos(B); } } List[Max]; double dist(Point a,Point b) { return sqrt((a-b)*(a-b)); } int Stack[Max],top; bool _cmp(Point p1,Point p2)//极角排序 { double tmp = (p1-List[0])^(p2-List[0]); if(sgn(tmp)>0) { return true; } else if(sgn(tmp)==0 && sgn(dist(p1,List[0])-dist(p2,List[0]))<=0) { return true; } else { return false; } } void Graham(int n)//凸包 { Point p0; int k = 0; p0=List[0]; for(int i=1; i<n; i++) { if((p0.y>List[i].y)||(p0.y==List[i].y&&p0.x>List[i].x)) { p0=List[i]; k=i; } } swap(List[k],List[0]); sort(List+1,List+n,_cmp); if(n==1) { top=1; Stack[0]=0; return ; } if(n==2) { top= 2 ; Stack[0]=0; Stack[1]=1; return ; } Stack[0]= 0 ; Stack[1]=1; top=2; for(int i=2; i<n; i++) { while(top>1&&sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0) top--; Stack[top++]=i; } } double Get(int n)//计算矩形的最小面积 { double ant,ans ,dis ; double x,y; double sum = INF; Point a; for(int i=0; i<n; i++) { a=List[Stack[(i+1)%n]]-List[Stack[i]]; ant = atan2(a.y,a.x);//倾斜角 x = 0; y = 0; for(int j=0; j<n; j++) { a=List[Stack[(j+1)%n]]-List[Stack[j]]; dis =sqrt(a.x*a.x+a.y*a.y); ans = atan2(a.y,a.x); x+=fabs(dis*sin(ans-ant));//映射总和 y+=fabs(dis*cos(ans-ant));//映射总和 } sum = min(x*y,sum); } return sum/4; } int main() { int n; while(scanf("%d",&n)&&n) { top = 0; for(int i=0; i<n; i++) { scanf("%lf %lf",&List[i].x,&List[i].y); } Graham(n); printf("%.4f\n",Get(top)); } return 0; }
相关文章推荐
- imageView实现图片缩放和旋转
- 导向滤波实现代码以及使用颜色先验去雾算法
- How to Increase Your Professional Reputation
- 学习笔记(4)——磁盘与文件系统
- linux命令学习——ps和netstat
- Linux sudoers error解决办法
- 57,字符串的基本知识
- 题目1151:位操作练习
- Linux c 算法与数据结构--栈
- 【Python】Python 三种导入模块的方法和区别
- eclipse debug不了 Cannot connect to VM
- 获取状态栏高度
- 聚类分析:基本概念梳理
- PHP面向对象 1.6 常见的关键字
- 条件概率项目相似性
- JDBC连接MYSQL数据库示例
- Hadoop WordCount代码
- 端口为8100的openoffice注册为windows系统服务
- 深度学习(二十)基于Overfeat的图片分类、定位、检测-2014 ICLR
- 推荐!手把手教你使用Git