--- description: UVa 429 解題心得 --- UVa 429 解題心得 === # 題目 [**題目點我**] ## 懶人大意 :::info 每筆測資一開始先給許多字串建構**字典** 接下來輸入兩個字串為 **起始字** 及 **目標字** **輸出**從起始字到目標字需要的**操作次數** ::: ## 此時 :::warning 阿 沒啥想法 看看hint "**BFS**"(廣度優先搜尋) -->跟圖有關係 ::: ## 圖 狀態看成點,狀態A可透過**一次操作**轉移至狀態B看成**狀態A到狀態B存在一條有向邊** 那從狀態S到狀態T最少要幾次操作,再透過BFS求得S到T的最短路徑 ## 注意事項 :::danger IO 極度麻煩 ::: ## 那怎麼寫呢?? 直接看註解ㄅ # code ```cpp= #include<bits/stdc++.h> using namespace std; #define maxn 205 int n;//n筆測資 vector<string> dic;//字典大全 map<string,int> vertex;//用map去搞定每個字串的編號 編號就是之後圖上的頂點 vector<int> adj[maxn];//用adjacency來存圖上的連通情況 int dis[maxn];//距離 bool vis[maxn];//BFS用 int bfs(int u,int v){ //初始化 memset(dis,0,sizeof dis); memset(vis,0,sizeof vis); dis[u]=0;vis[u]=1; //開始BFS queue<int> q; q.push(u); while(!q.empty()){ int now=q.front();q.pop(); if(now==v)break; for(auto i:adj[now]){ if(vis[i])continue; q.push(i); dis[i]=dis[now]+1;//步數加1 vis[i]=1; } } return dis[v]; } int main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin>>n; for(int count=0;count<n;count++){ //初始化 dic.clear(); vertex.clear(); for(int i=0;i<=maxn;i++)adj[i].clear(); string s; int index=0; while(cin>>s){ if(s=="*")break; dic.push_back(s); vertex[s]=index; for(int i=0;i<index;i++){//往回配對,看看有沒有和當前字串s需操作次數<=1的 int different=0; for(int j=0;j<s.size();j++){ if(s[j]!=dic[i][j])different++; } if(different<=1){ adj[index].push_back(i); adj[i].push_back(index); } } index++; } //終於建好圖了 string qu;//question cin.ignore(); while(getline(cin,qu)){//先依次讀整行 if(qu=="")break;//遇到空白行跳出 string str1,str2; //切成兩個字串 int i=0; for(i=0;i<qu.size();i++){ if(qu[i]==' ')break; else str1+=qu[i]; } i++; for(;i<qu.size();i++){ if(qu[i]==' ')break; else str2+=qu[i]; } /* 程式碼64~73行的更簡便的方法 用.find找空白 再用strtok切出來 */ cout<<str1<<' '<<str2<<' '<<bfs(vertex[str1],vertex[str2])<<endl; } if(count!=n-1)cout<<endl; } return 0; } ``` >[name=陳奕帆] ###### tags: `UVa`