1 条题解
-
0
解题思路
-
分类顶点:
- 首先,将所有顶点(除了原点)根据其所在的象限进行分类。四个象限的定义如下:
- 第一象限:(x > 0), (y > 0)
- 第二象限:(x < 0), (y > 0)
- 第三象限:(x < 0), (y < 0)
- 第四象限:(x > 0), (y < 0)
- 根据题目描述,多边形的顶点最多分布在三个象限中。
- 首先,将所有顶点(除了原点)根据其所在的象限进行分类。四个象限的定义如下:
-
计算斜率:
- 对于每个象限内的顶点,计算其与原点的斜率 (k = \frac{y}{x})(注意处理 (x = 0) 的情况,但题目说明没有顶点在坐标轴上)。
- 在每个象限内,斜率是单调递增或单调递减的。需要根据这一点对斜率进行排序。
-
确定斜率排序方向:
- 对于每个象限,选择一个顶点作为“起始点”,然后根据其他顶点的斜率与起始点的关系确定排序方向(递增或递减)。
- 具体来说,可以选取象限内 (x) 或 (y) 绝对值最大的点作为起始点,然后根据其他点的斜率与起始点的斜率比较确定顺序。
-
连接顶点:
- 从原点出发,按照排序后的顺序依次连接顶点,确保每次转向的角度是逆时针的(即外角为正)。
- 可以通过计算相邻边之间的叉积来判断转向方向。
-
具体步骤:
- 将所有顶点(除了原点)分类到对应的象限。
- 对于每个象限,计算所有顶点的斜率,并根据单调性排序。
- 确定每个象限内顶点的访问顺序。
- 将所有象限的顶点按逆时针方向连接起来,形成最终的顶点序列。
示例解析
以示例输入为例:
-
顶点分类:
- 第一象限:((60, 30)), ((80, 20)), ((90, 10))
- 第三象限:((-30, -40)), ((-30, -50)), ((-10, -60))
- 第四象限:((70, -50)), ((50, -60)), ((90, -20))
-
斜率计算与排序:
- 第一象限:
- 斜率:(\frac{30}{60} = 0.5), (\frac{20}{80} = 0.25), (\frac{10}{90} \approx 0.111)
- 斜率递减,排序为 ((60, 30)), ((80, 20)), ((90, 10))
- 第三象限:
- 斜率:(\frac{-40}{-30} \approx 1.333), (\frac{-50}{-30} \approx 1.666), (\frac{-60}{-10} = 6)
- 斜率递增,排序为 ((-30, -40)), ((-30, -50)), ((-10, -60))
- 第四象限:
- 斜率:(\frac{-50}{70} \approx -0.714), (\frac{-60}{50} = -1.2), (\frac{-20}{90} \approx -0.222)
- 斜率递增,排序为 ((50, -60)), ((70, -50)), ((90, -20))
- 第一象限:
-
连接顶点:
- 从原点出发,按照第三象限、第四象限、第一象限的顺序连接顶点(逆时针方向)。
- 具体顺序:
- 原点 ((0, 0))
- 第三象限:((-30, -40)), ((-30, -50)), ((-10, -60))
- 第四象限:((50, -60)), ((70, -50)), ((90, -20))
- 第一象限:((90, 10)), ((80, 20)), ((60, 30))
- 最终顺序与示例输出一致。
代码实现(伪代码)
#include <iostream> #include <cmath> #include <stdio.h> #include <algorithm> using namespace std; struct point { double x,y; }p[50],pp; double cross(point a,point b,point c) { return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y) ; } bool cmp(point a,point b) { int cr = cross(a,b,pp) ;//判断顺时针还是逆时针 if(cr > 0) return true ; else if(cr < 0) return false ; } int main() { int cnt = 0; while (scanf("%lf %lf",&p[cnt].x,&p[cnt].y) != EOF) { ++cnt; } pp.x = pp.y = 0 ; sort(p+1,p+cnt,cmp); for (int i = 0 ; i < cnt ; i++) { cout<<"("<<p[i].x<<","<<p[i].y<<")"<<endl; } return 0; }
-
- 1
信息
- ID
- 1008
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者