UVA - 1606 Amphiphilic Carbon Molecules 極角掃描法
阿新 • • 發佈:2018-07-12
坐標系 turn ios 題目 sin operator 排序 bool tps
題目:點擊查看題目
思路:這道題的解決思路是極角掃描法。極角掃描法的思想主要是先選擇一個點作為基準點,然後求出各點對於該點的相對坐標,同時求出該坐標系下的極角,按照極角對點進行排序。然後選取點與基準點形成的線對點進行掃描,基準線為遍歷選取,掃描線掃過的點,減去基準線掃過的點即為所要求的點的數量。同時註意到我們要求的是線兩邊的兩種點的數量,於是一種點比如黑點可以旋轉180度,然後之考察這180度內的百點數量即可。本題的基準點選取復雜度為O(n),極角排序復雜度O(nlogn),掃描復雜度O(n),復雜度為O(N2logN + N2),可視為O(N2logN)
AC代碼:
1 #include <iostream> 2#include <cmath> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int maxn = 1000 + 5; 8 9 struct point{ 10 int x, y, color; 11 double angle; 12 bool operator < (const point& temp) const { 13 return angle < temp.angle; 14 } 15 }point[maxn], cpoint[maxn];16 17 bool judge(struct point& A, struct point& B) { 18 return A.x*B.y - A.y*B.x >= 0; 19 } 20 21 int solve(int n) { 22 if(n <= 3) return n; 23 24 int ans = 0; 25 for(int i = 0; i < n; i++) { 26 int index = 0; 27 for(int j = 0; j < n; j++) { 28 if(j == i) continue; 29 cpoint[index].x = point[j].x - point[i].x; 30 cpoint[index].y = point[j].y - point[i].y; 31 if(point[j].color) { 32 cpoint[index].x = -cpoint[index].x; 33 cpoint[index].y = -cpoint[index].y; 34 } 35 cpoint[index].angle = atan2(cpoint[index].y, cpoint[index].x); 36 index++; 37 } 38 sort(cpoint, cpoint+index); 39 40 int st = 0, ed = 0, cnt = 2; 41 while(st < index) { 42 if(st == ed) { 43 ed = (ed + 1)%index; 44 cnt++; 45 } 46 while(st != ed && judge(cpoint[st], cpoint[ed])) { 47 ed = (ed + 1)%index; 48 cnt++; 49 } 50 51 cnt--; 52 st++; 53 54 ans = max(ans, cnt); 55 } 56 } 57 return ans; 58 } 59 60 int main() 61 { 62 int n; 63 while(cin >> n && n) { 64 for(int i = 0; i < n; i++) { 65 cin >> point[i].x >> point[i].y >> point[i].color; 66 } 67 cout << solve(n) << endl; 68 } 69 return 0; 70 }
UVA - 1606 Amphiphilic Carbon Molecules 極角掃描法