POJ 3320 Jessica's Reading Problem (尺取)

Description

给出一段长度为\(n\)的整数序列,求包含所有出现过的数的连续区间的最小长度。

Input

第一行给出序列长度\(n\),第二行给出\(n\)个整数,表示这个序列。\(n \leqslant 10^6\)

Output

输出一个整数,表示满足条件的区间的最小长度。

Sample Input

5
1 8 8 8 1

Sample Output

2

Solution

求连续区间,尺取问题。限制条件是下限,区间要包含每一种数。依次推进左端点,对于每个左端点,右端点向右直到找到第一个满足条件的位置,更新答案。如果右端点直到最右端仍然找不到合法区间,就跳出。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 10;

int a[N];
map<int, int> mp;

int main()
{
	int n;
	scanf("%d", &n);
	mp.clear();
	for (int i = 1; i <= n; i++) scanf("%d", a + i), mp[a[i]]++;
	int sum = mp.size();
	mp.clear();
	int r = 1, cnt = 0, ans = INF;
	for (int l = 1; l <= n; l++)
	{
		while (r <= n && cnt < sum)
		{
			mp[a[r]]++;
			if (mp[a[r]] == 1) cnt++;
			r++;
		}
		if (cnt < sum) break;
		ans = min(ans, r - l);
		mp[a[l]]--;
		if (mp[a[l]] == 0) cnt--;
	}
	printf("%d\n", ans);
	return 0;
}

http://poj.org/problem?id=3320

posted @ 2017-08-13 10:25  达达Mr_X  阅读(131)  评论(0)    收藏  举报