luogu P2564 [SCOI2009]生日礼物 & P3029 [USACO11NOV]牛的阵容Cow Lineup

背景:

类似的题目。

题目传送门:

https://www.luogu.org/problemnew/show/P2564
https://www.luogu.org/problemnew/show/P3029

题意:

n n n个珠子,且有 m m m种颜色。现在你需要选出一段包含所有的颜色,且长度尽可能短,求最小长度。

思路:

还是很好想的。
我们先将珠子按照位置升序。
枚举最左边的珠子,一直找到最右边的珠子,使得其包含所有颜色,更新答案。
在枚举左边第二个珠子的时候,我们只需要将前一个珠子的贡献减去,然后同理在最右边的珠子往后搜即可。
时间复杂度: Θ ( n l o g n ) \Theta(nlogn) Θ(nlogn)(要排序)。

P 2564 P2564 P2564代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
	int n,m,ans=2147483647;
	struct node{int x,pos;} a[1000010];
	int tot[100];
bool cmp(node x,node y)
{
	return x.pos<y.pos;
}
int main()
{
	int t,x,op=0;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&t);
		for(int j=1;j<=t;j++)
		{
			a[++op].x=i;
			scanf("%d",&a[op].pos);
		}
	}
	sort(a+1,a+n+1,cmp);
	int head=0,tail=0,cnt=0;
	for(;head<=n;head++)
	{
		while(cnt<m&&tail<n)
		{
			tail++;
			if(!tot[a[tail].x]) cnt++;
			tot[a[tail].x]++;
		}
		if(cnt==m) ans=min(ans,a[tail].pos-a[head].pos);
		tot[a[head].x]--;
		if(!tot[a[head].x]) cnt--;
	}
	printf("%d",ans);
}

P 3029 P3029 P3029代码:

#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
map<int,int> MAP;
	int n,m,ans=2147483647;
	struct node{int x,pos;} a[50010];
	int tot[50010];
bool cmp(node x,node y)
{
	return x.pos<y.pos;
}
int main()
{
	int tmp=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d %d",&a[i].pos,&a[i].x);
		if(!MAP[a[i].x]) MAP[a[i].x]=++tmp,m++;
	}
	sort(a+1,a+n+1,cmp);
	int head=1,tail=1,cnt=0;
	tot[MAP[a[1].x]]=cnt=1;
	for(;head<=n;head++)
	{
		while(cnt<m&&tail<n)
		{
			tail++;
			if(!tot[MAP[a[tail].x]]) cnt++;
			tot[MAP[a[tail].x]]++;
		}
		if(cnt==m) ans=min(ans,a[tail].pos-a[head].pos);
		tot[MAP[a[head].x]]--;
		if(!tot[MAP[a[head].x]]) cnt--;
	}
	printf("%d",ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值