题意: 给出n个用知识点(整数)的页码, 求得能够复习所有出现的知识点的最小连续页码数
题解: 毫无疑问这道题目符合尺取的不断右移, 左移的特征
- 如果还能发现未复习的点或复习点数量小于总数则右移
- 如果遍历完依然没有复习完则退出循环
- 否则试图左移
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const LL maxn = 1e6+10;
int P, p[maxn];
set<int> all;
map<int, int> m;
int main()
{
scanf("%d",&P);
for(int i = 1; i <= P; i++)
scanf("%d",&p
[i]), all.insert(p[i]);
int i = 1, j = 1, n = all.size(), ans = 1<<30, sum = 0;
while(1){
//依次遍历直至所有点均复习到
while(j <= P && sum < n)
if(m[p[j++]]++ == 0) sum++; //出现新的知识点
if(sum < n) break;
ans = min(ans, j-i);
if(--m[p[i++]] == 0) sum--; //某个知识点出现次数为0了
}
printf("%d\n",ans);
return 0;
}