Maximum Winter-Contest 2011 A: Shopping
keyword
尺取り法 C++
問題概要
長さM(<5*10^4)の文字列MとN(<=8)個の文字が与えられる。Nの文字が全て出現するような区間の最小幅を求める問題。
解法
蟻本に載ってる尺取り法の例題とほとんど同じ。なので詳細は蟻本参照のこと。
const int MAX_M = 52009; int N, M; int cnts[0x100]; bool ch[0x100]; char wants[20]; char prods[MAX_M]; int solve(){ int ans = M; int s=0,t=0,cnt=0; for(int i=0; i<0x100; i++) ch[i] = false; for(int i=0; wants[i]; i++) ch[wants[i]] = true; for(int i=0; i<0x100; i++) cnts[i] = 0; while(1){ while(t<M && cnt<N){ if(ch[prods[t]] && cnts[prods[t]]++ == 0){ cnt++; } t++; } if(cnt < N) break; ans = min(ans, t - s); if(ch[prods[s]] && --cnts[prods[s]] == 0){ cnt--; } s++; } return ans; } int main(){ while(scanf("%d%d ",&N,&M)){ if(!N && !M) break; scanf("%s ",wants); scanf("%s ",prods); printf("%d\n",solve()); } return 0; }