zoukankan      html  css  js  c++  java
  • UVa 1606 Amphiphilic Carbon Molecules (扫描法+极角排序)

    题意:平面上有 n 个点,每个点不是黑的就是白的,现在要放一个隔板,把它们分成两部分,使得一侧的白点数加上另一侧的黑点数最多。

    析:这个题很容易想到的就是暴力,不妨假设隔板至少经过两个点,即使不经过也可以通过平移使它经过,然后每次枚举两个点,当作隔板,枚举量是n*n,

    然后计算是 n,那么时间复杂度就是 n3 ,一定会超时的,我产可以这样想,先枚举一个点,然后绕这个点旋转,每扫过一个点,就动态修改两侧的点数,

    在转一周过程中,每个点至多扫到两次,这个过程复杂是 n,扫描前进行极角,时间复杂度是 n2*logn。这个题为了精度最好是叉乘来判。

    可以利用中心对称来简化运算。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <cstring>
    #include <cmath>
    
    using namespace std;
    const int maxn = 1000 + 5;
    struct node{
        int x, y;
        double rad;//极角
        node(int xx = 0, int yy = 0) : x(xx), y(yy) { }
        void inverse(){  x = -x;  y = -y;  }
        void cal(){  rad = atan2(y, x);  }
        bool operator < (const node &p) const{//排序
            return rad < p.rad;
        }
        friend node operator - (const node &lhs, const node &rhs){//减法
            return node(lhs.x-rhs.x, lhs.y-rhs.y);
        }
    };
    node a[maxn];
    int col[maxn], n;
    
    int cross(const node &p, const node &q){//叉乘
        return p.x * q.y - p.y * q.x;
    }
    
    int solve(){
        int ans = 0;
        for(int i = 0; i < n; ++i){
            vector<node> v;
            for(int j = 0; j < n; ++j){
                if(i == j)   continue;
                node temp = a[i] - a[j];//看成是向量
                if(col[j])  temp.inverse();//利用中心对称
                temp.cal();//计算极角
                v.push_back(temp);
            }
    
            sort(v.begin(), v.end());
            int cnt = 2, r = 0, m = v.size();
            for(int l = 0; l < m; ++l){//开始扫描
                if(l == r){ r = (r+1) % m;  ++cnt;  }
                while(l != r && cross(v[l], v[r]) >= 0){  ++cnt;  r = (r+1) % m; }
                --cnt;
                ans = max(ans, cnt);
            }
        }
        return ans;
    }
    
    int main(){
        while(scanf("%d", &n) == 1 && n){
            for(int i = 0; i < n; ++i)  scanf("%d %d %d", &a[i].x, &a[i].y, &col[i]);
    
            printf("%d
    ", solve());
        }
        return 0;
    }
    
  • 相关阅读:
    MySQL 优化
    Log4j2 中format增加自定义的参数
    MySQL 索引
    Linux中top和free命令详解(转)
    JAVA面试题
    Servlet3.0的可插拔功能
    开放通用Api,总有你喜欢的
    Git常用命令
    支付宝无法回调或者回调后验签失败
    Promise
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5647846.html
Copyright © 2011-2022 走看看