• P4385 [COCI2009]Dvapravca


    首先特判掉蓝点数量(<2)的情况。没有蓝点答案就是(n),有一个蓝点可以枚举一个红点,选择过这个蓝点和红点的一条线和在无穷远处的平行线(即这条线对应的两个半平面)。

    这里认为过一个点是与这个点无限接近,红点的话认为红点在平行线中,蓝点不在平行线中

    构造方案的时候想象两个阶段:

    • 如果有一条线不过蓝点,可以继续向外扩张直到过蓝点为止,现在两条平行线固定过两个蓝点
    • 如果没有平行线过红点,可以旋转这两条平行线知道一个平行线过红点为止。这个过程不会损失红点,而且可能加入新的红点。

    所以结论是:两条平行线肯定分别过两个蓝点,而且还有一条平行线过一个红点。

    先枚举一个蓝点和一个红点,一条线过这两个点;然后找到在两个方向距离这条线最近的蓝点,直接算红点数量即可。

    复杂度(O(n^3))

    直接做肯定过不去,所以先把整张图随机旋转,然后按照x坐标排序。

    时间的正确性请咨询@Leo______ 。

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    il int gi(){
        int x=0,f=0;char ch=getchar();
        while(!isdigit(ch))f^=ch=='-',ch=getchar();
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    struct point{double x,y;}r[1010],b[1010];
    il bool operator<(const point&a,const point&b){return a.x<b.x;}
    char col;
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int n=gi(),R=0,B=0;
        srand(time(NULL));
        double v=rand()%1000*0.1+0.1;
        for(int i=1;i<=n;++i){
            int _x=gi(),_y=gi();
            do col=getchar();while(col!='R'&&col!='B');
            if(col=='R')r[++R]=(point){sin(v)*_x-cos(v)*_y,sin(v)*_y-cos(v)*_x};
            else b[++B]=(point){sin(v)*_x-cos(v)*_y,sin(v)*_y-cos(v)*_x};
        }
        std::sort(r+1,r+R+1);
        std::sort(b+1,b+B+1);
        if(!B)return printf("%d
    ",n),0;
        int ans=0;
        double kk,bb,dist,dist_up,dist_dn;
        int upans,dnans;
        for(int i=1;i<=B;++i)
            for(int j=1;j<=R;++j){
                kk=1.0*(b[i].y-r[j].y)/(b[i].x-r[j].x),bb=b[i].y-kk*b[i].x;
                dist_up=1e18,dist_dn=1e18;
                for(int k=1;k<=B;++k)
                    if(k!=i){
                        dist=kk*b[k].x+bb-b[k].y;
                        if(dist<0){
                            if(-dist<dist_up)dist_up=-dist;
                        }else{
                            if(dist<dist_dn)dist_dn=dist;
                        }
                    }
                upans=1,dnans=1;
                for(int k=1;k<=R;++k)
                    if(k!=j){
                        dist=kk*r[k].x+bb-r[k].y;
                        if(dist<0){
                            if(-dist<=dist_up+1e-7)++upans;
                        }else{
                            if(dist<=dist_dn+1e-7)++dnans;
                        }
                    }
                ans=std::max(ans,std::max(upans,dnans));
            }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Grovvy初识
    在eclipse中安装插件
    解决 APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tas
    Axis2 webservice入门--Webservice的发布与调用
    一步一步教你自定义博客园(cnblog)界面
    Enum枚举
    并行与并发
    多线程join(加入)
    守护线程
    停止线程
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10234276.html
Copyright © 2020-2023  润新知