1081 AlvinZH的学霸养成记V
思路
中等题,计算几何。
这是一个排序问题,按极角排序。可以转化为叉积的应用,对于点A和B,通过叉积可以判断角度大小,共线时再判断距离。
叉积的应用。OA × OB = x1y2 - x2y1。
- OA × OB > 0:OA在OB的顺时针180°内;
- OA × OB = 0:三点共线,方向不一定相同;
- OA × OB < 0:OA在OB的逆时针180°内。
分析
注意数据范围,建议使用double。long long还是少用些好,真的。
参考代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#define MaxSize 100005
#define eps 1e-8
using namespace std;
struct Point {
string s;
double x, y;
Point(double x=0, double y=0):x(x),y(y) {}
};
int n;
Point P[MaxSize];
Point P0 = Point{0, 0};
Point operator - (const Point& A, const Point& B) {
return Point(A.x-B.x, A.y-B.y);
}
double Cross(const Point& A, const Point& B) {
return A.x*B.y - A.y*B.x;
}
double dis(Point A, Point B) {
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}
bool cmp(const Point& p1, const Point& p2)
{
double C = Cross(p1-P0, p2-P0);
return C ? C > 0 : dis(P0, p1) < dis(P0, p2);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
while(cin >> n)
{
for(int i = 0; i < n; i++)
cin >> P[i].s >> P[i].x >> P[i].y;
sort(P, P+n, cmp);
for(int i = 0; i < n; i++)
cout << P[i].s << "\n";
cout << "\n";
}
}