1. 程式人生 > >2016級算法第六次上機-D.AlvinZH的學霸養成記V

2016級算法第六次上機-D.AlvinZH的學霸養成記V

logs null markdown 可以轉化 turn stream ring amp tdi

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"; } }

2016級算法第六次上機-D.AlvinZH的學霸養成記V