首页 > 代码库 > (寒假集训) 调查

(寒假集训) 调查

调查

时间限制: 1 Sec  内存限制: 128 MB
提交: 30  解决: 10
[提交][状态][讨论版]

题目描述

      Ezio作为一名刺客,调查情报是必不可少的环节,比如目标最近的活动安排之类的情报还是很有用的。
      Ezio现在有一份调查列表,上面有n个人,每个人有一个编号,编号在1到m之间,编号记录的是这个人与哪一条情报有关,Ezio现在要调查1到m所有的情报,每条情报只需要调查与该条情报有关的一个人即可,由于时间关系,Ezio想要调查连续的一段人,并且调查的人数尽量少。

输入

共两行,第一行两个数n,m
第二行n个数 第i个数是,第i个人的编号。每两个数中间有一个空格隔开,结尾无空格。

输出

一个数,满足条件的最少人数。数据保证有解。

样例输入

7 6
6 1 2 4 4 5 3

样例输出

7

提示

数据范围
n<=1000000 m<=n

【分析】双指针

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define inf 2e9
#define met(a,b) memset(a,b,sizeof a)
typedef long long ll;
using namespace std;
const int N = 1e6+5;
const int M = 4e5+5;
int n,m;
int l=0,r=0;
int cnt[N],sum=0,ans=inf;
int a[N];
int main() {
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=0;i<n;i++){
        cnt[a[i]]++;
        r=i;
        if(cnt[a[i]]==1)sum++;
        if(sum>=m){
            for(int j=l;j<=r;j++){
                cnt[a[j]]--;
                if(!cnt[a[j]]){
                    ans=min(r-j+1,ans);
                    //printf("i=%d j=%d ans=%d l=%d r=%d\n",i,j,ans,l,r);
                    l=j+1;
                   sum--;
 
 
                    break;
                }
            }
        }
 
    }
    printf("%d\n",ans);
    return 0;
}

 

(寒假集训) 调查