【洛谷P1638】逛画展

题目大意:给定 N 个数字组成的序列,求刚好拥有所有 M 种数字的最短区间。

题解:双指针算法是一种对于暴力的优化算法,对于这道题来说,一个显然的暴力是:对于序列中每一个位置 pos,计算出这个位置右边恰好满足条件的位置 f[pos],时间复杂度为 \(O(n^2)\)。考虑对于每一个位置的计算位置,计算位置的值单调不降,因此,这就没有必要重复计算一些位置,直接扫描一遍即可统计出答案。因此,采用双指针扫描即可。
双指针算法的步骤如下:

  1. 未满足条件,则右端点不断向右扩展。
  2. 若仍不满足条件,则退出循环。
  3. 统计答案贡献。
  4. 左端点左移一个单位。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxm=2010;
const int maxn=1e6+10;

int n,m,a[maxn],cnt[maxm];

void solve(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	int len=n+1,x,y;
	for(int l=1,r=1,now=0;;){
		while(r<=n&&now<m)now+=!cnt[a[r++]]++;
		if(now<m)break;
		if(len>r-l)len=r-l,x=l,y=r-1;
		now-=!--cnt[a[l++]];
	}
	printf("%d %d\n",x,y);
}

int main(){
	solve();
	return 0;
} 
posted @ 2019-03-01 21:13  shellpicker  阅读(384)  评论(0)    收藏  举报