• UVa 1606 (极角排序) Amphiphilic Carbon Molecules


    如果,没有紫书上的翻译的话,我觉得我可能读不懂这道题。=_=||

    题意:

    平面上有n个点,不是白点就是黑点。现在要放一条直线,使得直线一侧的白点与另一侧的黑点加起来数目最多。直线上的点可以看作位于直线的任意一侧。

    分析:

    首先假设直线经过两个点,否则可以移动直线使其经过两个点,并且总数不会减少。

    所以,我们可以先枚举一个基点,然后以这个点为中心。

    围绕基点将其他点按照极角排序,将直线旋转,统计符合要求的点的个数。

    小技巧:

    如果将所有的黑点以基点为中心做一个中心对称,则符合要求的点的个数就变成了直线一侧的点的个数。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int maxn = 1000 + 10;
     6 
     7 int n, color[maxn];
     8 
     9 struct Point
    10 {
    11     int x, y;
    12     Point(int x=0, int y=0):x(x), y(y) {}
    13     double rad;
    14     bool operator < (const Point& rhs) const
    15     { return rad < rhs.rad; }
    16 }op[maxn], p[maxn];
    17 
    18 Point operator - (const Point& A, const Point& B)
    19 { return Point(A.x-B.x, A.y-B.y); }
    20 
    21 int Cross(const Point& A, const Point& B)
    22 { return A.x*B.y - A.y*B.x; }
    23 
    24 int solve()
    25 {
    26     //if(n <= 3) return n;
    27     int ans = 0;
    28     for(int i = 0; i < n; ++i)
    29     {//枚举基点
    30         int k = 0;
    31         for(int j = 0; j < n; ++j) if(i != j)
    32         {
    33             p[k] = op[j] - op[i];
    34             if(color[j]) { p[k].x = -p[k].x; p[k].y = -p[k].y; }//将黑点做个中心对称
    35             p[k].rad = atan2(p[k].y, p[k].x);
    36             k++;
    37         }
    38         sort(p, p+k);
    39 
    40         int L = 0, R = 0, cnt = 2;
    41         for(; L < k; ++L)
    42         {//统计p[L]到p[R]之间的点
    43             if(L == R) { R = (R+1)%k; cnt++; }
    44             while(L != R && Cross(p[L], p[R]) >= 0) { R = (R+1)%k; cnt++; }//当区间大于180度停止
    45             cnt--;
    46             ans = max(ans, cnt);
    47         }
    48     }
    49     return ans;
    50 }
    51 
    52 int main()
    53 {
    54     freopen("in.txt", "r", stdin);
    55 
    56     while(scanf("%d", &n) == 1 && n)
    57     {
    58         for(int i = 0; i < n; ++i) scanf("%d%d%d", &op[i].x, &op[i].y, &color[i]);
    59         printf("%d
    ", solve());
    60     }
    61 
    62     return 0;
    63 }
    代码君
  • 相关阅读:
    十个经典排序算法
    筛选法求2000以内的10个以上连续非素数组
    算法学习路线
    git 文件重命名
    一个github账户多台电脑代码提交
    SQL起别名
    多个Python环境的构建:基于virtualenv 包
    git学习:忽略部分文件
    git学习:多人协作,标签管理
    git学习4:分支管理
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4277934.html
Copyright © 2020-2023  润新知