​https://oj.ismdeep.com/problem?id=2388​

jxustOJ 2388 最短区间(贪心,思维)_原始数据


分析:维护一个区间[l, i],不断去重,每达到包含所有m种数就记录

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define d(x) cout << (x) << endl
using namespace std;
typedef long long ll;

const int N = 1e6 + 10;
const int M = 2020;
int a[N]; //原始数据
int b[M]; //记录区间[l, i]中每种数出现次数
int n, m;
int main()
{
int ans = 0, res = 0, MIN = INF; //res代表出现过几种数
scanf("%d%d", &n, &m);
int l = 1;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
if (!a[i]) //跳过零
continue;
if (!b[a[i]]) //某种数第一次出现res++
res++;
b[a[i]]++; //记录每种数出现次数
while (a[l] == 0)
l++; //跳过零
while (b[a[l]] > 1) //如果在区间 l, i中出现过a[l],去重
{
b[a[l]]--;
l++; //右移l
while (a[l] == 0)
l++;
}
if (res == m)
MIN = min(MIN, i - l + 1);
}
if (res != m)
cout << -1 << endl;
else
cout << MIN << endl;
return 0;
}