CF Array

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值