牛客 Cow Lineup 尺取法

问题:

Farmer John has hired a professional photographer to take a picture of some of his cows.  Since FJ's cows represent a variety of different breeds, he would like the photo to contain at least one cow from each distinct breed present in his herd.

FJ's N cows are all standing at various positions along a line, each described by an integer position (i.e., its x coordinate) as well as an integer breed ID.  FJ plans to take a photograph of a contiguous range of cows along the line.  The cost of this photograph is equal its size -- that is, the difference between the maximum and minimum x coordinates of the cows in the range of the photograph. 

Please help FJ by computing the minimum cost of a photograph in which there is at least one cow of each distinct breed appearing in FJ's herd.

输入描述:

* Line 1: The number of cows, N (1 <= N <= 50,000).
* Lines 2..1+N: Each line contains two space-separated positive integers specifying the x coordinate and breed ID of a single cow.  Both numbers are at most 1 billion.

输出描述:

* Line 1: The smallest cost of a photograph containing each distinct breed ID.

示例1

输入

6
25 7
26 1
15 1
22 3
20 1
30 1

输出

4

说明

There are 6 cows, at positions 25,26,15,22,20,30, with respective breed IDs
7,1,1,3,1,1.
The range from x=22 up through x=26 (of total size 4) contains each of the
distinct breed IDs 1, 3, and 7 represented in FJ's herd.

题意:给出N头牛的 X 坐标和品种 ID,找最小包含所有牛 ID 的区间长度。

思路:先将N头牛按X坐标从小到大进行排序,然后用尺取法,找到一个最小区间。

AC代码:

#include<stdio.h>
#include<string.h>
#include<map>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define ll long long
#define N 50100
struct node
{
    ll x,y;
}q[N];
bool zmh(node a,node b){return a.x<b.x;}
map<ll,int>mp;
int n;
int main()
{
    mp.clear();
    int ans=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&q[i].x,&q[i].y);
        if(mp[q[i].y]==0)mp[q[i].y]=1,ans++;
    }
    mp.clear();
    sort(q+1,q+1+n,zmh);
    int l=1,sum=0;
    ll maxx=0x3f3f3f3f3f3f;
    for(int i=1;i<=n;i++)//尺取法
    {
        mp[q[i].y]++;
        if(mp[q[i].y]==1)sum++;
        while(sum==ans&&mp[q[l].y]>1)//只有满足条件才能踢出队首
        {mp[q[l].y]--,l++;}
        if(sum==ans)maxx=min(maxx,q[i].x-q[l].x);
    }
    printf("%lld\n",maxx);

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值