洛谷OJ P1032 字串变换 解题报告
洛谷OJ P1032 字串变换 解题报告
by MedalPluS
【题目描述】
已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则):
A1$ -> B1$
A2$ -> B2$
规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$、A2$ 可以变换为 B2$ …。
例如:A$='abcd' B$='xyz'
变换规则为:
‘abc’->‘xu’ ‘ud’->‘y’ ‘y’->‘yz’
则此时,A$ 可以经过一系列的变换变为 B$,其变换的过程为:
‘abcd’->‘xud’->‘xy’->‘xyz’
共进行了三次变换,使得 A$ 变换为B$
【输入描述】
键盘输人文件名。文件格式如下:
A$ B$
A1$ B1$ \
A2$ B2$ |-> 变换规则
... ... /
所有字符串长度的上限为 20
【输出描述】
输出至屏幕。格式如下:
若在 10 步(包含 10步)以内能将 A$ 变换为 B$ ,则输出最少的变换步数;否则输出"NO ANSWER!"
【分析】
一开始拿到题目感觉有的懵懵哒,然后就明白了,这里翻译一下火星文:
给你两个字符串s1,s2,再给你许多许多变换方式使得s1=s2,求最少步数,大于10就输出NO ANSWER
我想,这不就是搜索求最优值问题么?然后就自然地想到了迭代加深(这里不赘述)
也就是最多层次为10,结果还是莫名其妙的TLE了。。。
然后算了一下,对于变换方式,可能有许多许多,这也就意味着解空间树不是一个二叉树,k叉树!也就是nk的复杂度,很明显TLE么。。
为什么要用迭代加深呢?怕空间不够!来算一下空间,20*20*19/2<107所以也就是虚惊一场,其实空间足够大
但是普通的BFS绝对会TLE的,这题有个特点,那就是知道起始点和终止点
然后我们采用双向BFS,加快速度
然后就AC了
【代码】
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #include <map> 5 #include <cstdlib> 6 #include <queue> 7 using namespace std; 8 9 const int maxn=1001; 10 11 struct node{ 12 int dfn; 13 string data; 14 }; 15 16 int l; 17 string c[maxn],c_[maxn];//c=>c_ 18 string s1,s2; 19 map<string,int> hash_f,hash_b; 20 queue<node> f,b; 21 22 string Getstr(string s,int l,int r){ 23 string base; 24 while(l<=r) 25 base+=s[l++]; 26 return base; 27 } 28 29 void expand_f(){ 30 node head=f.front(); 31 string tmp,cc,res; 32 f.pop(); 33 if(head.dfn+1>10)return; 34 int i,j,k,kk; 35 for(i=0;i<head.data.size();i++) 36 for(j=i;j<head.data.size();j++) 37 { 38 tmp=Getstr(head.data,i,j); 39 cc=""; 40 for(k=0;k<i;k++)cc+=head.data[k]; 41 res=cc; 42 for(k=1;k<=l;k++) 43 if(tmp==c[k]) 44 { 45 res+=c_[k]; 46 for(kk=j+1;kk<head.data.size();kk++) 47 res+=head.data[kk]; 48 if(hash_b[res]){printf("%d",hash_b[res]+head.dfn+1);exit(0);} 49 if(hash_f[res])continue; 50 else hash_f[res]=head.dfn+1; 51 f.push((struct node){head.dfn+1,res}); 52 res=cc; 53 } 54 } 55 } 56 57 void expand_b(){ 58 node head=b.front(); 59 string tmp,cc,res; 60 b.pop(); 61 if(head.dfn+1>10)return; 62 int i,j,k,kk; 63 for(i=0;i<head.data.size();i++) 64 for(j=i;j<head.data.size();j++) 65 { 66 tmp=Getstr(head.data,i,j); 67 cc=""; 68 for(k=0;k<i;k++)cc+=head.data[k]; 69 res=cc; 70 for(k=1;k<=l;k++) 71 if(tmp==c_[k]) 72 { 73 res+=c[k]; 74 for(kk=j+1;kk<head.data.size();kk++) 75 res+=head.data[kk]; 76 if(hash_f[res]){printf("%d",hash_f[res]+head.dfn+1);exit(0);} 77 if(hash_b[res])continue; 78 else hash_b[res]=head.dfn+1; 79 b.push((struct node){head.dfn+1,res}); 80 res=cc;//clear 81 } 82 } 83 } 84 85 void bfs(){ 86 int ex,len1,len2; 87 hash_f[s1]=0; 88 hash_b[s2]=0; 89 f.push((struct node){0,s1}); 90 b.push((struct node){0,s2}); 91 while(1){ 92 len1=f.size(); 93 len2=b.size(); 94 if(len1==len2 && !len2)break; 95 //按秩拓展 96 if(len1>len2){ 97 expand_f(); 98 if(len2)expand_b(); 99 } 100 else { 101 expand_b(); 102 if(len1)expand_f(); 103 } 104 } 105 } 106 107 int main(){ 108 cin>>s1>>s2; 109 l=1; 110 while(cin>>c[l]){ 111 cin>>c_[l]; 112 l++; 113 } 114 l--; 115 bfs(); 116 printf("NO ANSWER!"); 117 return 0; 118 }