[题解] [Noip模拟题]博览购票 C++

[Noip模拟题]博览购票

  • 题目
    • Description
    • Input
    • Output
      • Sample Input
      • Sample Output
  • 思路
  • 代码

题目

[Noip模拟题]博览购票

Description

博览馆正在展出由世上最佳的M位画家所画的图画。人们想到博览馆去看这几位大师的作品
。可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,a和b,
代表要看展览中的第a幅至第b幅画(包含a和b)之间的所有图画,而门票的价钱就是一张图画
一元。人们希望入场后可以看到所有名师的图画(至少各一张)。可是又想节省金钱……请你
写一个程序决定购买门票时的a值和b值。

Input

第一行是N和M,分别代表博览馆内的图画总数及这些图画是由多少位名师的画所绘画的。
其后的一行包含N个数字,它们都介于1和M之间,代表该位名师的编号。
N<=1000000,M<=2000

Output

a和b(a<=b)由一个空格符所隔开。
保证有解,如果多解,输出a最小的。

Sample Input

12 5
2 5 3 1 3 2 4 1 1 5 4 3

Sample Output

2 7

思路

把每次读入的画家放在队列里。用数组记录访问了多少次,再把每个取出来检查,如果满足有m人,且比上一次优,就记录a和吧

代码

#include
using namespace std;
int n,m;
int k[1000005];
int vis[2010];
int main(){
	int a,b,cnt=1e9,r=0,tot=0,l=1;
	cin>>n>>m;
	queue<int> q;
	for(int i=1;i<=n;i++){
		cin>>k[i];
		q.push(k[i]);
		r++;
		if(!vis[k[i]]){
			tot++;
		}
		vis[k[i]]++;
		while(vis[q.front()]>1 && l<r){
			l++;
			vis[q.front()]--;
			q.pop();
		}
		if(tot==m){
			if(r-l+1<cnt){
				cnt=r-l+1;
				a=l;
				b=r;
			}
		}
	}
	cout<<a<<" "<<b;
	return 0;
}

你可能感兴趣的:([题解] [Noip模拟题]博览购票 C++)