標籤:
題目連結:
http://www.codeforces.com/problemset/problem/666/A
題目大意:
給一個單詞,分為首碼和尾碼兩部分,前置長度不得小於5,尾碼長度只能2或3,請輸出尾碼的個數和所有的尾碼,要求所有尾碼均不重複。
分析:
其實這道題沒有太多的需要人類智慧的演算法(我也不會),直接上DP基本都能過。一開始想當然的窮舉,結果喜聞樂見的瞬間爆炸了…
DP之前注意要加一個vis數組記錄開始位置和長度,防止重複計算屬於首碼裡的詞。代碼中用set儲存答案純屬個人喜好,也可以用數組之類的代替,應該沒太大區別…(我沒試過,錯了後果自負)。複雜度也不太會算,提交返回46ms似乎挺快,如有大神會算複雜度,歡迎在下面評論。(對,這個博主就是啥都不會還出來浪…)
代碼:(渣渣代碼,如有雷同,那就雷同唄)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cmath> 7 #include<vector> 8 #include<map> 9 #include<stack>10 #include<set>11 #include<cstdlib>12 #include<deque>13 #include<queue>14 #include<bitset>15 #include<functional>16 #include<utility>17 #include<list>18 #include<iomanip>19 #include<ctime>20 #include<cassert>21 using namespace std;22 23 char str[10024];24 bool vis[10024][4];25 set<string> ans;26 set<string>::iterator it;27 28 int main()29 {30 int len,sum=0;31 scanf("%s",str);32 len=strlen(str);33 memset(vis,true,sizeof(vis));34 vis[len][0]=false;35 for(int i=len;i>=5;i--)36 {37 for(int j=0;j<4;j++)38 {39 40 if(!vis[i][j])41 {42 string x="",y="";43 for(int k=0;k<j;k++)44 y=y+str[i+k];45 for(int k=1;(i-k)>=5&&k<4;k++)46 {47 x=str[i-k]+x;48 if(x!=y&&k>1) 49 {50 ans.insert(x);51 vis[i-k][k]=false;52 }53 }54 }55 }56 }57 printf("%d\n",int(ans.size()));58 for(it=ans.begin();it!=ans.end();it++)59 {60 cout<<*it<<endl;61 }62 return 0;63 }
666A-Reberland Linguistics(動態規劃)