您的位置:首页 > 其它

洛谷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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: