Jessica's Reading Problem 尺取法 POJ 3320

原题 

     Jessica's Reading Problem

题目大意:  选一段长度为   k   的区间使其包含所有元素,询问 最小 k

Input

     第一行输入 一个数  n  ,接下来输入  n  个数。

     5

     1 8 8 8 1

Output

   输出最小  k .

   2

解题思路:

          从左往右依次取,如果不够的时候,就往右边扩 
           如果足够的话,就往右边缩。

          用 set 记录所有不重复的元素个数。 用 map 记录是否被取过。

#include<cstdio>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
const int maxn = 1000005;
set<int> se;     
map<int,int> m; 
int a[maxn];
int main(){
	int n;
	se.clear();
	m.clear();
	scanf("%d",&n);
	for(int i = 0;i < n;i++){
		scanf("%d",&a[i]);
		se.insert(a[i]);   // set 不重复性 
	}
	int sum = se.size();    //sum 为不重复的元素个数 
	int s = 0,l = 0,r = 0;
	int answer = 1000005;
	while(1){
		while(r < n && s < sum){
			if(m[a[r]] == 0){   //  出现一次  
				s++;	    // 和加  1 
			}
			m[a[r]]++;   // map 记录 该数出现的次数 
			r++;         //  不满足情况,右边  向右走 
		}
		if(s < sum){
			break;     //  完全遍历一次,退出 
		}
		answer = min(answer,r-l);   //满足情况下的最小 数 
		m[a[l]]--;        // map 消去它的一次记录 
		if(m[a[l]] == 0){  // 如果只出现了一次 
			s--;   // 总和减一 
		}
		l++;    // 左边向右走 
	} 
	printf("%d\n",answer);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/error311/article/details/81265678