UVALive 4617 Simple Polygon(顺/逆时针输出所有点/极角排序)
来源:互联网 发布:淘宝怎么预约快递 编辑:程序博客网 时间:2024/05/28 05:19
题目链接:
UVALive 4617 Simple Polygon
题意:
将平面所有点都用上,构成一个多边形,顺时针(或逆时针)输出点的顺序。
分析:
多边形有可能是凸的也有可能是凹的。
先找到最左下角的点(x值优先),然后对其余点以最左下角为基点极角排序。除去最左侧的一系列和point[0]共线的点,其余的点的顺序即是逆时针的点的顺序。
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <climits>using namespace std;const int MAX_N=2010;const double eps=1e-10;int T,n;int ans[MAX_N];struct Point{ double x,y; int index; Point () {} Point (double x,double y) : x(x),y(y) { } Point operator + (const Point& rhs) const{ return Point(x+rhs.x,y+rhs.y); } Point operator - (const Point& rhs) const { return Point(x-rhs.x,y-rhs.y); } Point operator * (const double d) const { return Point(d*x,d*y); } double dis(const Point& rhs) const{ return sqrt((x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y)); } double dot(const Point& rhs) const{ return (x*rhs.x-y*rhs.y); } double cross(const Point& rhs) const{ return (x*rhs.y-y*rhs.x); }}point[MAX_N];inline bool cmp(Point a,Point b){//按照最左下角极角排序 double res=(a-point[0]).cross(b-point[0]); if(res!=0.0) return res>0;//res>0说明b在左侧,此时a的极角较小 else return a.dis(point[0])<b.dis(point[0]); //共线时按照距离从小到大排序}inline void solve(){ //找到最左下角顶点,优先x最小,其次y最小 int k=0; for(int i=0;i<n;i++){ if(point[i].x<point[k].x||(point[i].x==point[k].x&&point[i].y<point[k].y)){ k=i; } } swap(point[0],point[k]); sort(point+1,point+n,cmp); //排序从下标1开始,因为point[0]就是起点 int end=n-2; //找到最后的顶点end,使得point[end],point[end+1]和point[0]不共线 while(end>0){ double res=(point[end]-point[0]).cross(point[end+1]-point[0]); if(res!=0.0) break; end--; } //从point[end+1]到point[n-1]都是和point[0]共线的点,即point[end+1]..point[n-1],point[0]都在一条直线上 //因为极角排序时是按照到point[0]距离从小到大排序,所以这些点的逆时针顶点应该是按照距离从大到小考虑 //point[end+1]实际上应该是第n-1个点,point[n-1]实际上应该时第end+1个点 for(int i=end+1;i<n;i++){ ans[i]=point[n+end-i].index; } for(int i=0;i<=end;i++){ ans[i]=point[i].index; } for(int i=0;i<n;i++){ printf("%d%c",ans[i],i==n-1?'\n':' '); }}int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%lf%lf",&point[i].x,&point[i].y); point[i].index=i; } solve(); } return 0;}
0 0
- UVALive 4617 Simple Polygon(顺/逆时针输出所有点/极角排序)
- POJ 2007 Scrambled Polygon 凸包点排序逆时针输出
- poj 2007 Scrambled Polygon 凸包点排序逆时针输出
- POJ 2007 || Scrambled Polygon(逆时针输出凸包顶点,以原点为起始点
- Scrambled Polygon(poj2007极角排序输出凸包)
- POJ 2007 Scrambled Polygon(点的极角排序)
- Scrambled Polygon (极角排序)
- poj2007-Scrambled Polygon (极角排序)
- POJ 2007 Scrambled Polygon (凸包输出点路径)
- 将多边形点按照逆时针排序
- poj Scrambled Polygon 2007 (凸包基础点排序)
- poj 2007 Scrambled Polygon(极角排序)
- POJ 2007 Scrambled Polygon(简单极角排序)
- POJ 2007:Scrambled Polygon (极角排序)
- poj 2007 Scrambled Polygon 极角排序
- POJ 2007 Scrambled Polygon(极角排序)
- POJ 2007 Scrambled Polygon 极角排序
- HDU-2007 Scrambled Polygon 极角排序
- Maven Scrop分析
- vs常见问题
- HDU 1174 爆头(几何---叉积)
- hdu 1671 Phone List
- PHP7之新增运算符
- UVALive 4617 Simple Polygon(顺/逆时针输出所有点/极角排序)
- java-利用synchronized实现volatile的功能
- 网页元素居中问题
- java面向对象的多态的问题
- 深入理解运算符重载
- 【UNREAL ENGINE 游戏开发】开篇之UE4的BLUEPRINT(蓝图)与C++(新童鞋必看)
- storyboard之 prepareForSegue:sender:
- 线程和进程
- atitit.词法分析原理 词法分析器 (Lexer)