zoukankan      html  css  js  c++  java
  • uva1606 Amphiphilic Carbon Molecules 极角排序+扫描线划窗

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1<<29;
    const double EPS=1e-10;
    const double Pi=acos(-1.0);
    
    struct Point
    {
        int x,y,c;
        double rad;
        friend bool operator<(Point A,Point B)
        {
            return A.rad<B.rad;
        }
        friend Point operator-(Point A,Point B)
        {
            return {A.x-B.x,A.y-B.y};
        }
        void debug()
        {
            printf("x=%2d y=%2d c=%d
    ",x,y,c);
        }
    };Point p[maxn],t[maxn];
    int n;
    
    bool Left(Point A,Point B)
    {
        return A.x*B.y-A.y*B.x>=0;
    }
    
    int solve(int k)
    {
        if(n<=2) return n;
        int cnt=0;
        REP(i,1,n){
            if(i!=k){
                t[cnt]=p[i]-p[k];
                t[cnt].c=p[i].c;
                if(t[cnt].c){
                    t[cnt].x=-t[cnt].x;
                    t[cnt].y=-t[cnt].y;
                }
                t[cnt].rad=atan2(t[cnt].y*1.0,t[cnt].x*1.0);
                cnt++;
            }
        }
        int res=1;
        sort(t,t+cnt);
        for(int L=0,R=0,tmp=2;L<cnt;L++){
            if(L==R) R=(R+1)%cnt,tmp++;
            while(L!=R&&Left(t[L],t[R])) R=(R+1)%cnt,tmp++;
            tmp--;
            res=max(res,tmp);
        }
        return res;
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        while(cin>>n,n){
            REP(i,1,n) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].c);
            int ans=0;
            REP(i,1,n) ans=max(solve(i),ans);
            cout<<ans<<endl;
        }
        return 0;
    }
    
    /**
    题意:
        平面上有n个点,每个点为白点或黑点,放置一隔板,使一侧的白点数+另一侧的黑点数最大。
        隔板上的点可视为任意一侧。
    分析:
        由于最优时,隔板一定经过至少两个点,所以枚举基准点,然后再枚举隔板上的另一点确定隔板方向,
        极角排序后进行划窗统计。复杂度n^2*logn。
        这里有个技巧,确定基准点后,可以将所有的黑点关于基准点中心对称到另一侧,统计时只需统计一侧的点数就可以了。
    类型:
        扫描线划窗。
    注意事项:
        恶心的扫描线。。。
    坑点:
    总结:
        划窗并不只在维护数列时用到。。。平面上的点也可以,这时一般需要先极角排序。
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/--560/p/5029128.html
Copyright © 2011-2022 走看看