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

题目:

我是超链接

题解:

不知道为什么放到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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值