调查
时间限制: 1 Sec 内存限制: 128 MB
提交: 30 解决: 10
[提交][状态][讨论版]
题目描述
Ezio作为一名刺客,调查情报是必不可少的环节,比如目标最近的活动安排之类的情报还是很有用的。
Ezio现在有一份调查列表,上面有n个人,每个人有一个编号,编号在1到m之间,编号记录的是这个人与哪一条情报有关,Ezio现在要调查1到m所有的情报,每条情报只需要调查与该条情报有关的一个人即可,由于时间关系,Ezio想要调查连续的一段人,并且调查的人数尽量少。
Ezio现在有一份调查列表,上面有n个人,每个人有一个编号,编号在1到m之间,编号记录的是这个人与哪一条情报有关,Ezio现在要调查1到m所有的情报,每条情报只需要调查与该条情报有关的一个人即可,由于时间关系,Ezio想要调查连续的一段人,并且调查的人数尽量少。
输入
共两行,第一行两个数n,m
第二行n个数 第i个数是,第i个人的编号。每两个数中间有一个空格隔开,结尾无空格。
第二行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 ",i,j,ans,l,r); l=j+1; sum--; break; } } } } printf("%d ",ans); return 0; }