ZOJ 2967 Colorful Rainbows

暴力。

先删掉一些边,平行的线只保留$b$最大的。然后暴力,每次放入第$i$条边,和还没有被完全覆盖的边都算一遍,更新一下。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0);
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
}
double INF=999999999999999.0;
#define eps 1e-8
#define zero(x) (((x)>0?(x):-(x))<eps)

struct point
{
    double x,y;
};

struct line
{
    point a,b;
    double K,B;
    double ll,rr;
} L[6000],tmp[6000];

int T,n;
int f[6000];

bool cmp(line a,line b)
{
    if(a.K!=b.K) return a.K>b.K;
    return a.B>b.B;
}

point intersection(point u1,point u2,point v1,point v2)
{
    point ret=u1;
    double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
             /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
    ret.x+=(u2.x-u1.x)*t;
    ret.y+=(u2.y-u1.y)*t;
    return ret;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);

        for(int i=0; i<n; i++) scanf("%lf%lf",&tmp[i].K,&tmp[i].B);
        sort(tmp,tmp+n,cmp);

        int sz=0;
        L[sz++]=tmp[0];
        for(int i=1; i<n; i++)
        {
            if(abs(L[sz-1].K-tmp[i].K)<eps) continue;
            L[sz++]=tmp[i];
        }

        for(int i=0; i<sz; i++)
        {
            point p1;
            p1.x=1;
            p1.y=L[i].K*1+L[i].B;
            point p2;
            p2.x=-1;
            p2.y=L[i].K*(-1)+L[i].B;

            L[i].a=p1, L[i].b=p2;
            L[i].ll=-INF, L[i].rr=INF;
        }

        memset(f,0,sizeof f);

        for(int i=1; i<sz; i++)
        {
            for(int j=0; j<i; j++)
            {
                if(f[j]) continue;

                point jiao = intersection(L[i].a,L[i].b,L[j].a,L[j].b);

                if(L[i].K>=0&&L[i].K>L[j].K)
                {
                    L[i].ll=max(L[i].ll,jiao.x);
                    L[j].rr=min(L[j].rr,jiao.x);
                }

                else if(L[i].K>=0&&L[i].K<L[j].K)
                {
                    L[i].rr=min(L[i].rr,jiao.x);
                    L[j].ll=max(L[j].ll,jiao.x);
                }

                else if(L[i].K<0&&L[j].K>L[i].K)
                {
                    L[i].rr=min(L[i].rr,jiao.x);
                    L[j].ll=max(L[j].ll,jiao.x);
                }

                else if(L[i].K<0&&L[j].K<L[i].K)
                {
                    L[i].ll=max(L[i].ll,jiao.x);
                    L[j].rr=min(L[j].rr,jiao.x);
                }

                if(L[i].rr<=L[i].ll+eps) f[i]=1;
                if(L[j].rr<=L[j].ll+eps) f[j]=1;

            }
        }

        int ans=0;
        for(int i=0; i<sz; i++) if(f[i]==0) ans++;
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2017-02-16 18:28  Fighting_Heart  阅读(194)  评论(0编辑  收藏  举报