【問題描述】node
給出兩個單詞(開始單詞和結束單詞)以及一個詞典。找出從開始單詞轉換到結束單詞, 所須要的最短轉換序列。轉換的規則以下:ios
一、每次只能改變一個字母c++
二、轉換過程當中出現的單詞(除開始單詞和結束單詞)必須存在於詞典中算法
例如: 開始單詞爲:hit數組
結束單詞爲:cog函數
詞典爲:[hot,dot,dog,lot,log,mot]spa
那麼一種可能的最短變換是: hit -> hot -> dot -> dog -> cog,code
因此返回的結果是序列的長度 5;blog
注意: 一、若是不能找到這種變換,則輸出 0;ci
二、詞典中全部單詞長度同樣;
三、全部的單詞都由小寫字母構成;
四、開始單詞和結束單詞能夠不在詞典中。
【輸入文件】
共兩行,第一行爲開始單詞和結束單詞(兩個單詞不一樣),以空格分開。第二行爲若干 的單詞(各不相同),以空格分隔開來,表示詞典。單詞長度不超過 5,單詞個數不超過 30。
【輸出文件】
輸出轉換序列的長度。
【輸入樣例】
hit cog
hot dot dog lot log
【輸出樣例】
5
【數據範圍】
單詞長度不超過5,單詞個數不超過30;
這個題算法大概是搜索,這可真的是使人質壁分離。
還記得我烤雞寫了一個多小時呀qwq(果然仍是我太菜了),感受本身代碼能力真心很差呀,我可能也就for寫的足夠優秀了emmm。
(滾去寫這個題代碼了)
MY SOLUYION:
first.這個題讀入就很卡人,下面咱們來總結一下輸入若干個(題目未給出具體的數值)應該腫麼寫:
string a; cin>>a;//直接用string而後cin或scanf輸入就好;
while(ch!='\n'){ n++; scanf("%s",dic[n].g); ch=getchar(); }//由於輸入時兩個字符串之間會間隔一個空格,所以咱們getchar()掉這個空格,getchar的這個空格記爲ch,當ch='\n'(即說明讀到了回車),那麼很顯然的,就不該該讀下去了
char bj=' ',i=1;//bj即爲標記,i爲數組下標(多個數用數組比較方便) while(bj==' ')//由於輸完數要按空格 {cin>>a[++i]; bj=getchar(); 一行內輸入n個整數
//樓下捕捉一隻yjk神仙 while(cin>>s[++n]);
//好像神仙們都是這麼寫的,就我這種蒟蒻寫的這麼複雜emm
而後由於方便計算,我把str和end加入了這n個單詞以後,在字典有的單詞的基礎上+2
//輸入部分 scanf("%s",str); scanf("%s",end); len=strlen(str); while(ch!='\n'){ n++; scanf("%s",dic[n].g); ch=getchar(); } for(int i=0;i<len;i++) dic[n+1].g[i]=str[i],dic[n+2].g[i]=end[i]; n+=2;ss=n-1;ee=n;
next.由於數據比較小嘛,因此個人想法是開一個二維數組cy(chayi)[i][j],表示第i個單詞與第j個單詞的差別,而後大概應該多是用dfs計算,而後出結果;對於預處理:
//比較函數與預處理 int bj(char a[],char b[]){ int c=0; for(int i=0;i<len;i++) if(a[i]!=b[i]) c++; return c; } …… for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) cy[j][i]=cy[i][j]=bj(dic[i].g,dic[j].g),cy[i][i]=0;
end.代碼的核心dfs部分:
以上就是大體算法流程。
CODE:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> using namespace std; char str[5],end[5],ch; struct node1{ char g[5]; }dic[31]; int n,cy[35][35],len,ss,ee,ans,f[100],cnt; int bj(char a[],char b[]){ int c=0; for(int i=0;i<len;i++) if(a[i]!=b[i]) c++; return c; } bool vis[31]; int solve(int begin,int ans){ if(begin==ee) { f[++cnt]=ans; return 1; } int next; int bj=0; for(int i=1;i<=n;i++){ if(vis[i]) continue; if(i==begin) continue; if(cy[begin][i]!=1) continue; next=i;vis[next]=1; bj=1; solve(next,ans+1); vis[next]=0; } if(!bj) return 0; } int main(){ // freopen("word2.in","r",stdin); // freopen("word.out","w",stdout); scanf("%s",str); scanf("%s",end); len=strlen(str); while(ch!='\n'){ n++; scanf("%s",dic[n].g); ch=getchar(); } for(int i=0;i<len;i++) dic[n+1].g[i]=str[i],dic[n+2].g[i]=end[i]; n+=2;ss=n-1;ee=n; for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) cy[j][i]=cy[i][j]=bj(dic[i].g,dic[j].g),cy[i][i]=0; vis[ss]=1; if(solve(ss,1)==0)cout<<"0"<<endl; else{ sort(f+1,f+cnt+1); cout<<f[1]<<endl; } return 0; }
而後咱們看一下標程:
CODE:
//加一句註釋提醒本身並不想看標程,改天再看吧qwq
#include<cstdio> #include<iostream> #include<queue> #include<cstring> using namespace std; struct node{ string s; int dep; }; queue<node>q; string ss,st,s[31]; int vis[31]; int n=0; int can(string s,string t){ if(s.size()!=t.size()) return 0; int c=0; for(int i=0;i<s.size();i++) if(s[i]!=t[i]) c++; return c==1; } int bfs(){ memset(vis,0,sizeof(vis)); q.push((node){ss,1}); while(!q.empty()){ node cur=q.front();q.pop(); if(cur.s==st) return cur.dep;//是目標 if(can(cur.s,st)) return cur.dep+1;//再一步就是目標 for(int i=0;i<n;i++) if(!vis[i]&&can(cur.s,s[i])){ q.push((node){s[i],cur.dep+1}); vis[i]=1; } } return 0; } int main(){ freopen("word.in","r",stdin); freopen("word.out","w",stdout); cin>>ss>>st; while(cin>>s[n++]); cout<<bfs()<<endl; return 0; }
end-