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;
}
注意事项
- 在 \(x=0\) 时也要将其入队,检查后出队,因为此时也需要检查出队后的新
front
需不需要出队。 - 当这个颜色没有出现过时,才能给总计数 \(+1\) ,如果已经出现过前面就已经加过了。
- 如果把全部的颜色都算进去了,还没有达到 \(m\) 就不可能实现,输出 \(-1\) 。亦可在开始时判断颜色种类数是否可能满足条件。