p1166

拿到题后先分析题意:求n个牛棚中能够扩张的数量.

然后看数据范围确定解法:n<=25000不能写n^2枚举.坐标范围是[0,1000000],不论是时间还是空间不能写地图标记flag后判断...

考虑如果只有左右两个墙,问你能像左右拓展的牛棚数量.这个时候发现还是不能写整个[0,1000000]范围.因为可能会有两个边在同一个数列上并且这时候不会判断大小.能否写链表呢?每个i后面跟一串链表记录所有边,然后再跑双指针?貌似可以.

考虑这个代码复杂度极高的很捞的算法的出现过程.首先只有两个墙的思想是离散化的表现.因为能否扩张只需要考虑两两边的关系对吧.然后那个很捞的链表根本没用啊,为什么不写sort然后跑双指针呢?

好了A了.

bool flag[25010];
struct shu
{
    int x,ay,by;
    int i;
}a[50010];
bool Orz(shu x,shu y)
{
    if(x.x==y.x)
        return x.ay<y.ay;
    return x.x<y.x;
}
struct heng
{
    int y,ax,bx;
    int i;
}b[50010];
bool orz(heng x,heng y)
{
    if(x.y==y.y)return x.ax<y.ax;
    else 
        return x.y<y.y;
}
int n,ans;
int i,f,ax,ay,bx,by,zuo,you;
int main()
{
//freopen("123.in","r",stdin);
    n=read();
    for(i=1;i<=n;i++)
    {
        ax=read();
        ay=read();
        bx=read();
        by=read();
        f++;
        a[f].x=b[f].ax=ax;
        b[f].bx=bx;
        a[f].ay=b[f].y=ay;
        a[f].by=by;
        a[f].i=b[f].i=i;
        f++;
        b[f].ax=ax;
        b[f].bx=a[f].x=bx;
        a[f].ay=ay;
        b[f].y=a[f].by=by;
        a[f].i=b[f].i=i;
    }
    sort(a+1,a+1+f,Orz);
    sort(b+1,b+1+f,orz);
    for(zuo=you=1;zuo<=2*n;)
    {
        while(a[you+1].x==a[you].x)
            you++;
        for(i=zuo;i<you;i++)
        {
            for(f=i+1;f<=you;f++)
                if(a[i].by>=a[f].ay)
                    flag[a[i].i]=flag[a[f].i]=1;
                else break;
        }
        zuo=you=you+1;
    }
    for(zuo=you=1;zuo<=2*n;)
    {
        while(b[you+1].y==b[you].y)
            you++;
        for(i=zuo;i<you;i++)
        {
            for(f=i+1;f<=you;f++)
                if(b[i].bx>=b[f].ax)
                    flag[b[i].i]=flag[b[f].i]=1;
                else break;
        }
        zuo=you=you+1;
    }
    for(i=1,ans=n;i<=n;i++)
        ans-=flag[i];
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qywyt/p/9984619.html