POJ 3320

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40924940/article/details/83542032

题目翻译:

        有一本书,书上有 p 页内容,每一页有一个知识点(会用一个正数表示),假设存在一个区间,是区间内有全部出现过的知识点,求这个区间最小长度。

这道题思路还是比较明显的,涉及到了区间长度,正好运用到了之前提及的   尺取法  所以运用尺取法来解决这个问题。

但是比较不一样的地方是,因为出现的知识点数字标号可能不是连续的,可以先用 set 统计一共有几个知识点,之后可以用 map 来

进行出现过的知识点统计。由于之前没想到用 map wa了几次。。看了看白皮书。。参考了一下写了出来。建议先自己想一下,再来核对代码 AC代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
 
const int MAXN = 1e6 + 50;
int a[MAXN];
int p;
 
int main()
{
	while (scanf("%d", &p) != EOF)
	{
		for (int i = 0; i < p; i++)
			scanf("%d", &a[i]);
 
		set<int>all;
		for (int i = 0; i < p; i++)
			all.insert(a[i]);
		int n = all.size();
 
		int s = 0, t = 0, num = 0;
		map<int, int>count;
		int ret = p;
		for (;;)
		{
			while (t < p && num < n)//头部延伸
			{
				if (count[a[t]] == 0)
				{
					num++;
				} 
                count[a[t]]++,t++;
			}
			if (num < n) break;//结束
			ret = min(ret, t - s);//记录最小值
			if (count[a[s]] == 1)//尾部收缩
				num--;
            count[a[s]]--,s++;
		}
		printf("%d\n", ret);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40924940/article/details/83542032