題面:
變形課
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 26776 Accepted Submission(s): 9787
Problem Description
呃……變形課上Harry碰到了一點小麻煩,因爲他並不像Hermione那樣能夠記住所有的咒語而隨意的將一個棒球變成刺蝟什麼的,但是他發現了變形咒語的一個統一規律:如果咒語是以a開頭b結尾的一個單詞,那麼它的作用就恰好是使A物體變成B物體.
Harry已經將他所會的所有咒語都列成了一個表,他想讓你幫忙計算一下他是否能完成老師的作業,將一個B(ball)變成一個M(Mouse),你知道,如果他自己不能完成的話,他就只好向Hermione請教,並且被迫聽一大堆好好學習的道理.
Input
測試數據有多組。每組有多行,每行一個單詞,僅包括小寫字母,是Harry所會的所有咒語.數字0表示一組輸入結束.
Output
如果Harry可以完成他的作業,就輸出”Yes.”,否則就輸出”No.”(不要忽略了句號)
Sample Input
so
soon
river
goes
them
got
moon
begin
big
0
Sample Output
Yes.
分析:
此題做法很多,可以用BFS,DFS,和最短路算法來求解
本題解用Floyd算法來求解
將輸入單詞看做一個圖,單詞的開頭和結尾分別看成兩個點,連一條權值爲1的有向邊
求能否變成b開頭m結尾就是求從點b到點m的最短路徑
爲了方便實現,我們將a,b,……z分別編號爲0,1,2,3……25,用鄰接矩陣存圖即可
代碼:
#include<iostream>
#include<cstring>
#define maxn 27
#define INF 9999999
//最大值不能設成太大,否則d[i][k]+d[k][j]會溢出
using namespace std;
char in[1005];
int d[maxn][maxn];
int n;
void floyd(){
d[0][0]=0;
for(int k=0;k<maxn;k++){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++){
d[i][j]=min(d[i][j],d[i][k]+d[k][j]); //標準的flovd最短路
}
}
}
}
int main(){
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++) d[i][j]=INF;
}
while(cin>>in){
if(in[0]=='0'){
floyd();
if(d['b'-'a']['m'-'a']!=INF) cout<<"Yes."<<endl;
else cout<<"No."<<endl;
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++) d[i][j]=INF;
}
}
else{
d[in[0]-'a'][in[strlen(in)-1]-'a']=1;
}
}
}