hrbustoj 1305:多边形(计算几何,极角排序练习)

多边形

Time Limit: 1000 MS     Memory Limit: 65536 K

Total Submit: 113(42 users)   Total Accepted: 51(38 users) Rating:   

Special Judge: No

 

Description

一个封闭的多边形定义是被有限个线段包围。线段的相交点称作多边形的顶点,当你从多边形的一个顶点沿着线段行走时,最终你会回

 hrbustoj 1305:多边形(计算几何,极角排序练习)_第1张图片

到出发点。

凸多边形(convex)想必大家已经很熟悉了,下图给出了凸多边形和非凸多边形实例。

这里讨论的是在平面坐标的封闭凸多边形,多变形的顶点一个顶点在原点(x=0,y=0).图2显示的那样。这样的图形有两种性质。

 hrbustoj 1305:多边形(计算几何,极角排序练习)_第2张图片

 

第一种性质是多边形的顶点会在平面上少于等于三个象限,就如图二那样,第二向县里面没有多边形的点(x<0,y>0)。

为了解释第二种性质,假设你沿着多边形旅行,从原点(0,0)出发遍历每个顶点一次,当你遍历到除原点(0,0)时候,从这一点画一条和原点(0,0)的斜线。计算这种斜率。当计算完所有的斜率时候,这些斜率组成升序或降序顺序。

如图三所示。

 hrbustoj 1305:多边形(计算几何,极角排序练习)_第3张图片

 

Input

输入包含多组测试数据。

第一行输入一个整数n(50>n>0),其中n表示多边形顶点的个数,当n为0时表示结束。紧跟n行输入在平面中多边形的顶点整数x,y(-999<x,y<999),其中第一行是原点(0,0),其他的多边形顶点可能不是顺序给出。没有顶点在x,y坐标轴上,没有三个顶点共线。

Output

输出多边形的顶点,每个顶点一行,原点(0,0)首先输出。其他顶点的输出构成沿多边形(逆时针方向)构成一条旅游路线。输出格式为(x,y)如实例

Sample Input

10

0 0

70 -50

60 30

-30 -50

80 20

50 -60

90 -20

-30 -40

-10 -60

90 10

0

Sample Output

(0,0)

(-30,-40)

(-30,-50)

(-10,-60)

(50,-60)

(70,-50)

(90,-20)

(90,10)

(80,20)

(60,30)

Author

鲁学涛


 

  计算几何,极角排序

  极角排序的基础练习题,我用atan2做的,据说这可能会伤精度,so可以采用象限极角排序,不失精度。有兴趣的同学可以查查。

  极角的解释  极角排序(atan2方法+象限排序)详解

  手工排序代码

 1 #include <stdio.h>
 2 #include <math.h>
 3 typedef struct {  4     double x,y;  5 }Point;  6 int main()  7 {  8     int n;  9     while(scanf("%d",&n)!=EOF){ 10         if(n==0) break; 11         Point p[51]; 12         int i,j,num[51]; 13         for(i=1;i<=n;i++){    //输入点集
14             scanf("%lf%lf",&p[i].x,&p[i].y); 15             num[i] = i;    //排序的时候记录顺序
16  } 17         double a[51]; 18         a[1] = 0; 19         for(i=2;i<=n;i++) 20             a[i] = atan2(p[i].y,p[i].x);    //利用math库中的atan2(y,x)函数,求坐标(x,y)与x正半轴逆时针方向的夹角。
21         for(i=2;i<=n-2;i++)        //注意从2开始排序
22             for(j=2;j<=n-i+1;j++) 23                 if(a[j]>a[j+1]){ 24                     double t; 25                     t = a[j];a[j] = a[j+1];a[j+1] = t; 26                     int tt; 27                     tt=num[j];num[j]=num[j+1];num[j+1]=tt; 28  } 29         for(i=1;i<=n;i++)    //输出
30             printf("(%d,%d)\n",(int)p[num[i]].x,(int)p[num[i]].y); 31  } 32     return 0; 33 }

  利用sort函数排序代码

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <algorithm>
 4 using namespace std;  5 typedef struct {  6     double x,y;  7 }Point;  8 bool cmp(Point a,Point b)    //利用atan2的比较函数
 9 { 10     double d1 = atan2(a.y,a.x); 11     double d2 = atan2(b.y,b.x); 12     return d1 < d2; 13 } 14 int main() 15 { 16     int n; 17     while(scanf("%d",&n)!=EOF){ 18         if(n==0) break; 19         Point p[51]; 20         int i; 21         for(i=1;i<=n;i++){    //输入点集
22             scanf("%lf%lf",&p[i].x,&p[i].y); 23  } 24         sort(p+2,p+n+1,cmp);    //排序
25         for(i=1;i<=n;i++)    //输出
26             printf("(%d,%d)\n",(int)p[i].x,(int)p[i].y); 27  } 28     return 0; 29 }

 

Freecode : www.cnblogs.com/yym2013

你可能感兴趣的:(排序)