UVa1606 Amphiphilic Carbon Molecules (扫描法+极角排序)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa1606 Amphiphilic Carbon Molecules (扫描法+极角排序)相关的知识,希望对你有一定的参考价值。

链接:http://vjudge.net/problem/UVA-1606

分析:不妨先假设隔板一定经过至少两个点(否则可以移动隔板使其经过经过两个点,由于在隔板上的点可以看作是在任意一侧,所以总数并不会变小)。最简单的想法是,枚举两个点,然后输出两侧黑白点的个数,枚举量是O(n²),再加上统计的O(n),总时间复杂度是O(n³),太大。

  可以先枚举一个基准点,然后将一条直线绕这个基准点旋转。其它点要按照相对基准点的极角排序,这里有一个技巧就是把所有黑点或者白点的坐标作一个中心对称,这样以后就只需统计直线一侧点的总数,排好序后,设边的左端点L和右端点R,初始时L=R=0,每次枚举一个点L,L和基准点的连线作为基准边,将R相对于点基准边转过180°,每当扫过一个点,就动态修改(维护)两侧的点数,直到转到180°,然后更新ans最大值,将下一个点作为左端点L,此时前任左端点被移出扫描区域cnt--,继续不断移动右端点直至180°,期间维护最大值ans就好了。

 

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 1000 + 5;
 7 
 8 struct Point {
 9     int x, y;
10     double rad;
11     bool operator < (const Point& rhs) const {
12         return rad < rhs.rad;
13     }
14 } op[maxn], p[maxn];
15 
16 int n, color[maxn];
17 
18 bool Left(Point A, Point B) {
19     return A.x * B.y - A.y * B.x >= 0;
20 }
21 
22 int solve() {
23     if (n <= 2) return 2;
24     int ans = 0;
25     for (int i = 0; i < n; i++) {
26         int k = 0;
27         for (int j = 0; j < n; j++)
28             if (j != i) {
29                 p[k].x = op[j].x - op[i].x;
30                 p[k].y = op[j].y - op[i].y;
31                 if (color[j]) { p[k].x = -p[k].x; p[k].y = -p[k].y; }
32                 p[k].rad = atan2(p[k].y, p[k].x);
33                 k++;
34             }
35         sort(p, p + k);
36 
37         int L = 0, R = 0, cnt = 2;
38         while (L < k) {
39             if (L == R) { R = (R + 1) % k; cnt++; }
40             while (L != R && Left(p[L], p[R])) { R = (R + 1) % k; cnt++; }
41             cnt--;
42             L++;
43             ans = max(ans, cnt);
44         }
45     }
46     return ans;
47 }
48 
49 int main() {
50     while (scanf("%d", &n) == 1 && n) {
51         for (int i = 0; i < n; i++)
52             scanf("%d%d%d", &op[i].x, &op[i].y, &color[i]);
53         printf("%d\n", solve());
54     }
55     return 0;
56 }

 

以上是关于UVa1606 Amphiphilic Carbon Molecules (扫描法+极角排序)的主要内容,如果未能解决你的问题,请参考以下文章

UVa1606 Amphiphilic Carbon Molecules (扫描法+极角排序)

UVA - 1606 Amphiphilic Carbon Molecules (计算几何,扫描法)

UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法

UVa 1606 两亲性分子

POJ1598 ZOJ1315 HDU1606 UVA409 UVALive5493 Excuses, Excuses!文本

最短前缀