【藍橋vip試題】ALGO-24 演算法訓練 統計單詞個數
問題描述:
給出一個長度不超過200的由小寫英文字母組成的字母串(約定;該字串以每行20個字母的方式輸入,且保證每行一定為20個)。要求將此字母串分成k份 (1<k<=40),且每份中包含的單詞個數加起來總數最大(每份中包含的單詞可以部分重疊。當選用一個單詞之後,其第一個字母不能再用。例 如字串this中可包含this和is,選用this之後就不能包含t)。單詞在給出的一個不超過6個單詞的字典中。
要求輸出最大的個數。
輸入格式
第一行有二個正整數(p,k)
p表示字串的行數;
k表示分為k個部分。
接下來的p行,每行均有20個字元。
再接下來有一個正整數s,表示字典中單詞個數。(1<=s<=6)
接下來的s行,每行均有一個單詞。 輸出格式 每行一個整數,分別對應每組測試資料的相應結果。 樣例輸入 樣例輸入
1 3 thisisabookyouareaoh 4 is a ok sab
樣例輸出
7
樣例輸出
資料規模和約定
長度不超過200,1<k<=40,字典中的單詞數不超過6。
-----------分界線-----------
這道題算是很基礎的字串模擬題,資料規模只有200,暴力模擬就完事
#對於入門選手,講一下字串的比較:
兩個字串相等,就代表了他們對應下標的元素相同。我們需要知道字串的長度,然後用迴圈來依次比較。
#include<bits/stdc++.h> using字串比較namespace std; int main() { int len_a,len_b,flag; char a[10],b[10]; gets(a); gets(b); len_a=strlen(a); len_b=strlen(b); if(len_a!=len_b)//如果長度不一樣,那一定不同 printf("No\n"); else { flag=1;//flag是標記 //這裡用len_a或者len_b都可以,因為len_a==len_b for(int i=0;i<len_a;i++) {if(a[i]!=b[i])//如果a和b的對應位置元素出現不同的 { flag=0;//標記變成0,即為不同 break;/跳出迴圈,後面的就不用比了 } } if(flag==1) printf("Yes\n"); else printf("No\n"); } return 0; }
然後分開講一下程式碼思路:
1、輸入
題目給的輸入比較有意思,是每行20個字元,輸入p行。對於字串的讀入可以直接用getchar(),要記得讀掉換行符,不然會出錯。然後,二維陣列不方便換行,所以用了將原來的ch[i][j]換成了ch[i*20+j],這樣轉換下標就可以把輸入資料轉換為一維。
輸入部分程式碼:
cin>>p>>k; for(int i=0;i<p;i++) { getchar();//換行符!!! for(int j=0;j<20;j++) ch[i*20+j]=getchar();//正常資料讀入 } cin>>s; for(int i=0;i<s;i++) { cin>>d[i];//讀入字典 len[i]=strlen(d[i]);//len陣列記錄字典長度 }
2、判斷
判斷部分,遍歷每一個元素。假設他們都是頭,依次進行判斷,如果當前字元與字典中的某一串的頭相同,則繼續進行後續的判斷(我用了自定義的check函式)。如果當前的ch[i]可以作為一個頭來滿足一個單詞,則ans++,同時更新end。end是當前滿足的單詞的最後一個下標,更新他的條件在程式碼中。當出現同一個頭不同詞的時候,如果不滿足更新end條件,是不會增加ans的。
bool check(int i,int j) { for(int v=1;v<len[j];v++) { if(ch[i+v]!=d[j][v]) return 0; } return 1; }Check
for(int i=0;i<p*20;i++) { for(int j=0;j<s;j++) { flag=0; if(ch[i]==d[j][0]) { if( check(i,j) ) { if(end<i+len[j]) end=i+len[j]; ans++; flag=1; break; } } if( !flag && k>1 && i>end) k--; }
}
3、後續處理及輸出
經過思考,當無效元素足夠多的時候,可以隨便切並且對答案沒有影響。但是會出現一些不夠切的情況
比如:
給定字串為abcabc,字典僅有abc,需要分成k=3段
我們可以看到,如果不考慮分段的話,(abc)(abc)即為最優解,ans=2。但是這樣只分了兩段,為了滿足3段的條件,我們只能去浪費一個單詞來滿足分段。隨便分一下變成了 (abc)(ab)(c),這時滿足了k=3的需求,