洛谷P1638 逛画展
很经典的一道类似有一个头,一个尾,然后头和尾移动,从前往后扫一遍的题,我以前做过一道类似的,很相似,不过我不记得了,唉,可惜。正解是枚举区间的左右端点,右端点不断移动直到正好框住k种,此时,(r-l)与(j-i)比较,更新l,r,最后i++,直到i==n.
我一开始也没想到这样枚举,我想的是枚举框的长度,这样从小到大枚举,每次扫一遍判断是否包含k个,A了4个点,剩下的都TLE了。。。
#include<bits/stdc++.h> using namespace std; int a[1000001],b[2001]; int n,m,l,r; void Cin(int &x) { char c=getchar();x=0; while(c<‘0‘||c>‘9‘)c=getchar(); while(c<=‘9‘&&c>=‘0‘)x=x*10+c-‘0‘,c=getchar(); } int main() { Cin(n),Cin(m); r=0x7fffffff; for(int i=1;i<=n;i++) Cin(a[i]); for(int i=1,j=0,k=0;i<n;i++) { while(k<m&&j<n) { j++; if(j>n) break; if(b[a[j]]==0) k++; b[a[j]]++; } if(k==m&&(r-l)>(j-i)) l=i,r=j; b[a[i]]--; if(b[a[i]]==0)k--; } cout<<l<<‘ ‘<<r; }
时间: 2024-10-25 18:53:05