NKOJ 1095 气球游戏

NKOJ 1095 气球游戏

废话

  • 为什么要单独写一篇文章?

  • 因为卡了一个小时,令我十分生气,故好好总结避免下次还是不会。

思路

  • 类似与单调队列,但与单调队列维护的东西不同。

实现方法

  • 对于每一个输入

    • 加入队列。
    • 如果它不是 \(0\) 就给总颜色计数 \(+1\) ,并将这种颜色的数量也 \(+1\)
    • 只要队首的颜色数量大于一,就弹掉。
    • 如果总颜色计数,达到要求更新答案。
  • 如果答案 \(>n\) 就输出 \(-1\) ,否则直接输出。

代码

#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,cnt,ans=0x7fffffff;
int color[1000005];
queue<int> que;
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		int x;
		scanf("%d",&x);
		que.push(x);
		if(x!=0){
			if(color[x]==0) cnt++;//注意点2
			color[x]++;
		}
		while(color[que.front()]>1||que.front()==0){if(que.front()!=0) color[que.front()]--;que.pop();}//注意点1
		if(cnt==m) ans=min(ans,int(que.size()));
	}
	if(ans>n) puts("-1");//注意点3
	else printf("%d",ans);

	return 0;
}

注意事项

  1. \(x=0\) 时也要将其入队,检查后出队,因为此时也需要检查出队后的新 front 需不需要出队。
  2. 当这个颜色没有出现过时,才能给总计数 \(+1\) ,如果已经出现过前面就已经加过了。
  3. 如果把全部的颜色都算进去了,还没有达到 \(m\) 就不可能实现,输出 \(-1\) 。亦可在开始时判断颜色种类数是否可能满足条件。
posted @ 2024-12-14 09:42  hsr_ray  阅读(17)  评论(0)    收藏  举报