题目描述(在洛谷中查看)
已知有两个字串 A,BA,B 及一组字串变换的规则(至多 66 个规则):
A_1A1 -> B_1B1
A_2A2 -> B_2B2
规则的含义为:在 AA 中的子串 A_1A1 可以变换为 B_1B1 , A_2A2 可以变换为 B_2B2 …。
例如: AA =' abcdabcd ' BB =' xyzxyz '
变换规则为:
‘ abcabc ’->‘ xuxu ’‘ udud ’->‘ yy ’‘ yy ’->‘ yzyz ’
则此时, AA 可以经过一系列的变换变为 BB ,其变换的过程为:
‘ abcdabcd ’->‘ xudxud ’->‘ xyxy ’->‘ xyzxyz ’
共进行了 33 次变换,使得 AA 变换为 BB 。
输入输出格式
输入格式:
输入格式如下:
AA BB
A_1A1 B_1B1
A_2A2 B_2B2 |-> 变换规则
... ... /
所有字符串长度的上限为 2020 。
输出格式:
输出至屏幕。格式如下:
若在 1010 步(包含 1010 步)以内能将 AA 变换为 BB ,则输出最少的变换步数;否则输出"NO ANSWER!"
输入输出样例
输入样例#1: 复制
abcd xyz abc xu ud y y yz
输出样例#1: 复制
3
对于这题,我走了很多弯路,本来像这种求最优解的用bfs就好,而且我也是做的bfs这板块的题目,结果我却用了dfs(手动捂脸),瞎搞了很大 很大 半天,终于AC!!!
下面来看一下本蒟蒻的dfs,真的悲催。
1 #include"iostream" 2 #include"string" 3 #include"map" 4 using namespace std; 5 const int NoFind = string::npos,NONE = 999999999; 6 string s_start,s_final,s[10][2]; 7 int min1 = NONE,len,mx,mn = NONE,s_final_len; 8 map<string,int> ma; 9 int prune(string &str){ 10 if(str[0] != s_final[0]){ 11 for(int i = 0;i < len;i++){ 12 if(s[i][0][0] == str[0]){ 13 return false; 14 } 15 } 16 return true; 17 } 18 return false; 19 } 20 void dfs(string str,int n){ 21 //cout<<str<<' '<<n<<endl; 22 if(n > 10 || prune(str)){ //剪枝1(减去那些有不可能被替换的首字符的字符串) 23 return ; 24 } 25 if(ma.count(str) == 1){ //剪枝2(减去那些重复的字符串) 26 return ; 27 } 28 int strlen = str.length(); 29 if(mx * (10 - n) + strlen < s_final_len|| mn * (10 - n) + strlen > s_final_len){ //剪枝3(剪去那些10步内不可能得到的长度) 30 return ; 31 } 32 ma[str] = 1; 33 if(str == s_final && min1 > n){ 34 min1 = n; 35 return ; 36 } 37 for(int j = 0;j < strlen;j++){ 38 for(int i = 0;i < len;i++){ 39 string s_temp = str; 40 int pos = s_temp.find(s[i][0],j); 41 if(pos != NoFind){ 42 s_temp.replace(pos,s[i][0].length(),s[i][1]); 43 dfs(s_temp,n + 1); 44 } 45 } 46 } 47 } 48 int main(){ 49 cin>>s_start>>s_final; 50 cin.get(); 51 s_final_len = s_final.length(); 52 while(cin>>s[len][0]>>s[len][1]){ 53 int len1 = s[len][1].length() - s[len][0].length(); 54 mx = mx > len1 ? mx : len1; 55 mn = mn < len1 ? mn : len1; 56 len++; 57 } 58 dfs(s_start,0); 59 if(min1 == NONE){ 60 cout<<"NO ANSWER!"; 61 } 62 else{ 63 cout<<min1; 64 } 65 return 0; 66 }