【程式設計網格無水題】之【最短歧義串】
阿新 • • 發佈:2018-11-25
一個小小的字串,一個三歲小孩都能把它刪掉,但它卻可以累死所有的程式設計師……
就好比這道題,累死我了。
首先宣告,演算法來自於百度貼吧的 patricia_xiao 前輩,非常感謝,本蒟蒻不生產演算法,我只是演算法的搬運工。
附原帖地址http://tieba.baidu.com/p/2048370484
閒話結束,下面上題
考慮一個歧義串會有什麼樣的結構
拿樣例為例,iskill ,它可以拆分成 I 和 skill,也可以拆成 is 和 kill
那麼不同的拆分方式是什麼意思呢?
就是is 可以嚴格包含I ,剩下字串s 可以被 skill 嚴格包含 ,而skill 剩下的字串 kill 呢又等於字典中原有的 kill
這樣就構造好了一個歧義串。所以不同拆分的意思就是完美包含
有同學說自己case8總是空輸出,怎麼回事呢?
比如說A被B完美包含,B截掉A剩下的字串啊,很可能巨長……沒有字典中的原串可以包含它,但它卻可以包含字典中的某些原串……
那就看它能包含字典中哪些原串嘍,再截短
顯而易見,退出條件就是這個剩下的字串和字典中某個原串相等(或者再走一步,剩下的字串為0,但不推薦這麼想,因為有違歧義的原則)。
敲黑板!!!這題感覺單詞不能重複用,所以一定要標記哪些串用過了,不標記100%TLE (跟我念,te le,這單詞不念T L E)
下面上程式碼(註釋是方便除錯的時候搞事情的,因為我很懶,懶得裝程式設計環境所以一直在用線上IDE)
最後,黃旭東祝大家考啥啥掛(手動滑稽)聽說昨晚黃旭東和局座一起做客B站,咳咳咳,簡直生化危機,非抗奶人員請迅速撤離……#include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<climits> #include<cmath> using namespace std; string dic[110]; bool used[110]; int n,ans; string astr; void dfs(string substr,int templ,string tans){ //cout<<substr<<"mark"<<endl; //cout<<tans<<endl; for(int i=0;i<n;i++){ if(!used[i]){ //cout<<dic[i]<<endl; if(dic[i]==substr){ if(ans>templ+substr.length()){ ans=templ+substr.length(); astr=tans+substr; } return; }else if(dic[i].length()>substr.length()&&dic[i].find(substr,0)==0){ used[i]=true; string tstr=dic[i].substr(substr.length(),dic[i].length()-substr.length()); dfs(tstr,templ+substr.length(),tans+substr); used[i]=false; }else if(dic[i].length()<substr.length()&&substr.find(dic[i],0)==0){ used[i]=true; string tstr=substr.substr(dic[i].length(),substr.length()-dic[i].length()); dfs(tstr,templ+dic[i].length(),tans+dic[i]); used[i]=false; } } } return; } int main(){ ans=INT_MAX; memset(used,0,sizeof(used)); scanf("%d\n",&n); for(int i=0;i<n;i++) cin>>dic[i]; sort(dic,dic+n); for(int i=1;i<n;i++){ for(int j=0;j<i;j++){ if(dic[i].find(dic[j],0)==0&&dic[i]!=dic[j]){ used[i]=true; used[j]=true; const string tstr=dic[i].substr(dic[j].length(),dic[i].length()-dic[j].length()); dfs(tstr,dic[j].length(),dic[j]); used[i]=false; used[j]=false; } } } // printf("%d\n",ans); cout<<astr; return 0; }