版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}