UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法
题目:点击查看题目
思路:这道题的解决思路是极角扫描法。极角扫描法的思想主要是先选择一个点作为基准点,然后求出各点对于该点的相对坐标,同时求出该坐标系下的极角,按照极角对点进行排序。然后选取点与基准点形成的线对点进行扫描,基准线为遍历选取,扫描线扫过的点,减去基准线扫过的点即为所要求的点的数量。同时注意到我们要求的是线两边的两种点的数量,于是一种点比如黑点可以旋转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 }
版权声明:该博客版权归本人所有,若有意转载,请与本人联系