1. 程式人生 > >【Luogu1638】逛畫展

【Luogu1638】逛畫展

出現一次 log https 語文 表示 col 一個 ++ lan

點此進入原題

算法(有技巧的)模擬

題解

這題可以不用真實的隊列,只要用兩個變量模擬一下就可以啦

也可以說是枚舉的思想:這題很容易想到O(n^2)的枚舉區間的算法,容易TLE。先找到第一個包含所有不同數字的區間[i,j],然後讓i+1,同時枚舉j找到另一個區間,然後取j-i的最小值就OK辣。判斷不同的數字完全可以用桶解決

可能我的語文差了一點,具體看我的代碼吧(好難表述啊QAQ)

代碼

#include<cstdio>
const int N=1000005,M=2017;
int a[N],b[M],n,m,l,r=1<<30;
int main()
{
    scanf(
"%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1,j=0,k=0;i<=n;i++) //枚舉區間[i,j] { while(k<m) //枚舉j找到包含m個不同元素的區間[i,j].(k表示不同的數的個數) { j++; //小細節:j初值為0,提前自增,避免了一些麻煩 if(j>n) break; if(b[a[j]]==0) k++; //
此數未出現過,k++ b[a[j]]++; } if(k==m&&r-l>j-i) l=i,r=j; //修改最小值 b[a[i]]--; //i+1前將第i個數移出區間 if(b[a[i]]==0) k--; //如果此數在[i,j]中只出現一次並且現在被移出,那麽k-- } printf("%d %d",l,r); //最後輸出答案區間,結束~ }

【Luogu1638】逛畫展