洛谷OJ P1032 字串变换 解题报告
2015-05-10 00:02
281 查看
洛谷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了
【代码】
#include <iostream> #include <cstdio> #include <string> #include <map> #include <cstdlib> #include <queue> using namespace std; const int maxn=1001; struct node{ int dfn; string data; }; int l; string c[maxn],c_[maxn];//c=>c_ string s1,s2; map<string,int> hash_f,hash_b; queue<node> f,b; string Getstr(string s,int l,int r){ string base; while(l<=r) base+=s[l++]; return base; } void expand_f(){ node head=f.front(); string tmp,cc,res; f.pop(); if(head.dfn+1>10)return; int i,j,k,kk; for(i=0;i<head.data.size();i++) for(j=i;j<head.data.size();j++) { tmp=Getstr(head.data,i,j); cc=""; for(k=0;k<i;k++)cc+=head.data[k]; res=cc; for(k=1;k<=l;k++) if(tmp==c[k]) { res+=c_[k]; for(kk=j+1;kk<head.data.size();kk++) res+=head.data[kk]; if(hash_b[res]){printf("%d",hash_b[res]+head.dfn+1);exit(0);} if(hash_f[res])continue; else hash_f[res]=head.dfn+1; f.push((struct node){head.dfn+1,res}); res=cc; } } } void expand_b(){ node head=b.front(); string tmp,cc,res; b.pop(); if(head.dfn+1>10)return; int i,j,k,kk; for(i=0;i<head.data.size();i++) for(j=i;j<head.data.size();j++) { tmp=Getstr(head.data,i,j); cc=""; for(k=0;k<i;k++)cc+=head.data[k]; res=cc; for(k=1;k<=l;k++) if(tmp==c_[k]) { res+=c[k]; for(kk=j+1;kk<head.data.size();kk++) res+=head.data[kk]; if(hash_f[res]){printf("%d",hash_f[res]+head.dfn+1);exit(0);} if(hash_b[res])continue; else hash_b[res]=head.dfn+1; b.push((struct node){head.dfn+1,res}); res=cc;//clear } } } void bfs(){ int ex,len1,len2; hash_f[s1]=0; hash_b[s2]=0; f.push((struct node){0,s1}); b.push((struct node){0,s2}); while(1){ len1=f.size(); len2=b.size(); if(len1==len2 && !len2)break; //按秩拓展 if(len1>len2){ expand_f(); if(len2)expand_b(); } else { expand_b(); if(len1)expand_f(); } } } int main(){ cin>>s1>>s2; l=1; while(cin>>c[l]){ cin>>c_[l]; l++; } l--; bfs(); printf("NO ANSWER!"); return 0; }
相关文章推荐
- NOIP 2002 字串变换 解题报告
- NOIP 2002字串变换 解题报告(双向宽搜)
- 【未出现的字串】解题报告
- Leetcode 127. Word Ladder 字符变换 解题报告
- 2014百度之星资格赛解题报告:能量变换
- 2014百度之星资格赛解题报告:能量变换
- 解题报告PKU1159 最长公共字串 回文串 DP
- Leetcode 126. Word Ladder II 字符变换2 解题报告
- POJ - 1195 Mobile phones解题报告(二维树状数组)
- 洛谷 1578 奶牛沐场 最大子矩阵 解题报告
- 0-1背包问题(动态规划) 解题报告
- 第七次练习赛解题报告及标程
- [LeetCode] 501. Find Mode in Binary Search Tree 解题报告
- poj2251解题报告
- openjudge 9277 堆木头的解题报告
- NOIP2013 货车运输 解题报告(最大生成树+倍增lca)
- 2012金华邀请赛解题报告
- Intervals poj1089 解题报告
- 蓝桥杯 历届试题 买不到的数目 解题报告(完全背包,数论)
- 解题报告 之 ZOJ2332 Gems