[luogu2862][USACO06JAN]把牛Corral the Cows(二维队列)

来源:互联网 发布:5g网络概念 编辑:程序博客网 时间:2024/06/03 22:41

题目:

我是超链接

题解:

不知道为什么放到tarjan的分类
类似于一种二维的队列吧
排序+离散(当然这题数据小不用离散,但离散可以节约空间?)
离散之后y坐标已经排好序了,用a,b两个指针固定这个区间,顺便把这个区间里有的x标清楚一下
那就开始固定x的区间了,我固定一个区间之后直接看看两个固定区间的交集——–有多少个在范围内的x直接累加

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;struct hh{int x,y;}p[505];int mx,my,rx[505],ry[505],n,cc,ans,s[505];int cmp(hh a,hh b){return a.x<b.x;}int cmp1(hh a,hh b){return a.y<b.y;}bool check(int mid){        memset(s,0,sizeof(s));    int a=1,b=0;    while (b<n && ry[p[b+1].y]-ry[1]+1<=mid) s[p[++b].x]++;    for (;b<=n;s[p[++b].x]++)    {        while (ry[p[b].y]-ry[p[a].y]+1>mid) s[p[a++].x]--;         int c=1,d=0,sd=0,sc=0;        while (d<mx && rx[d+1]-rx[1]+1<=mid) sd+=s[++d];        for (;d<=mx;sd+=s[++d])        {            while (rx[d]-rx[c]+1>mid) sc+=s[c++];            if (sd-sc>=cc) return 1;          }    }    return 0;}int main(){    int i;    scanf("%d%d",&cc,&n);    for (i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);    sort(p+1,p+n+1,cmp);     for (i=1;i<=n;i++)     {        if (p[i].x>rx[mx]) rx[++mx]=p[i].x;        p[i].x=mx;    }    sort(p+1,p+n+1,cmp1);//离散     for (i=1;i<=n;i++)     {        if (p[i].y>ry[my]) ry[++my]=p[i].y;        p[i].y=my;    }    int l=1,r=max(rx[mx],ry[my]);    while (l<=r)    {        int mid=(l+r)>>1;        if (check(mid)) ans=mid,r=mid-1;        else l=mid+1;    }     printf("%d",ans);}
阅读全文
0 0