链接:这里
AC CODE
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n, m, mina = INF, minb = 2 * INF;
int a[1000006], mark[2005];
int main(){
cin >> n >> m;
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
}
mark[a[1]] = 1;
int cnt = 1;
for(int l = 1, r = 1; l <= n; ++l){
mark[a[l - 1]]--;
if(mark[a[l - 1]] == 0) cnt--;
while(cnt < m && r <= n){
r++;
if(mark[a[r]] == 0){
cnt++;
}
mark[a[r]]++;
}
if(cnt == m && r - l + 1 < minb - mina + 1){
mina = l, minb = r;
}
}
cout << mina << ' ' << minb;
return 0;
}
解题报告
寻找包含所有画师作品的最短序列长度,序列中同一画师可能重复出现,且选取最优解下左端点最小的序列。利用双指针算法。
l指针指向左端点,r指针指向右端点,cnt代表序列中已有的画师数量,a[]用来存放画师编号,mark[]用来记录序列中某画师的作品数目。
l从左往右顺序遍历,然后从序列中把第l - 1位作品扔出去,接着r一直往后遍历,把第r位画师的作品扔进去,如果这个画师之前未出现过,即mark[r] == 0,那么计数器++,当cnt == m时,或者r越界时退出,最后判断如果是画师满员了,则对区间长度进行比较,接着更新值。


664

被折叠的 条评论
为什么被折叠?



