http://codeforces.com/problemset/problem/224/B
题意:给你一个含有n个元素数组,让你求出这个数组的一个区间[ l , r ],满足在这个区间中含有 k 个不同的数,且不存在x, y
(l <= x <= y <= r) 也满足 区间[ x , y] 有k 个完全不同的数。即[l , r] 的任何一个子区间都不满足条件,但并不要求区间[ l,r ] 是最短的。
思路: 要使[l , r] 含有k个不同的数,而[l , r] 的任何一个子区间都不满足有k个不同的数,说明[l , r]的端点在这个区间中只出现一次,所以用hash数组记录下每个数出现的次数,然后以hash[i] = 1的i为区间的左端点 l ,然后 j 从 l+k-1 枚举,直到出现了k个完全不同的数为止。
#include<stdio.h>
#include<string.h>
int a[100010],hash[100010];
//每次从start 开始找hash值为1的数的下标
int find(int start)
{
while(a[start] == a[start+1])
start++;
return start;
}
int main()
{
int n,k;
while(~scanf("%d %d",&n,&k))
{
int l, r;
int cnt, flag, minl, minr,start;
memset(hash,0,sizeof(hash));
cnt = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
if(!hash[ a[i] ])
{
hash[ a[i] ] = 1;
cnt++;
}
}
if(cnt < k)
{
printf("-1 -1\n");
continue;
}
if(k == 1)
{
printf("1 1\n");
continue;
}
start = find(1);
flag = 0;
memset(hash,0,sizeof(hash));
for(int i = start; i <= n; i++)
{
l = i;
r = i+k-1;
cnt = 0;
memset(hash,0,sizeof(hash));
for(int g = i; g <= i+k-1; g++)
{
if(!hash[ a[g] ])
cnt++;
hash[ a[g] ] += 1;
}
if(cnt == k)
{
flag = 1;
minl = l;
minr = r;
break;
}
else
{
for(int g = i+k; g <= n; g++)
{
hash[ a[g] ] += 1;
if(hash[ a[g] ] == 1)
{
cnt++;
if(cnt == k)
{
if(hash[ a[i] ] == 1)
{
flag = 1;
minl = i;
minr = g;
break;
}
}
}
}
}
if(flag)
break;
else start = find(i+1);
}
if(flag == 1)
printf("%d %d\n",minl,minr);
else printf("-1 -1\n");
}
return 0;
}