题目本身其实并不难,但是细节特别特别多。。。。,我因为细节问题踩坑踩了一个小时,自从接触了C++,真的很有感触STL大法好
这道题使用广搜的算法,首先自然是一个结构体,里面存放当前字符串和到达当前字符串所需要的步数。首先将初始的字符串设置为A,当前步数设置为0,入队,开始广搜,每次从队列弹出一个元素,判断当前的字符串是否等于B并且当前到达当前的步数是否小于10,如果满足条件就保存结果退出,如果当前步数大于10,果断退出,上面两个条件都不满足的情况下,当前弹出队列的那个结构体元素,判断其字符串是否有子串可以转换为新的字符串,如果有就将转换后的字符串加入队列,并将其步数在上一步的基础上+1
这里要注意!!!几个踩坑的地方,如果当前的步数小于10步,但是队列已经为空了,那么上面的结束条件都不会满足,退出后res=0,但是实际上此时是无解的,所以最后还有一个特判,如果将弹出的结构体的字符串转换后,队列仍然为空,说明已经不能转换了,就将res设置为-1
**踩坑点2. **
program procedure
g ce
ra dur
am ee
ee am
最开始第一个入队的元素是program,那么其可以转换为proceram,progdurm,progree,这个自然没问题,但是还有这种情况!!
abaaaba abcdaba
a b
b d
d e
e f
f g
g c
这种情况,最开始第一个入队元素是abaaaba,然后看看转换规则,对于第一个转换规则a–>b,这里面可以转换5次,当时我只用str1.find(str2),匹配到第一个以后就不管了,其实后面还有可以匹配的,所以我们要使用str.find(str2,i)这里的i的范围是0–str.size()-1,并不是匹配到第一个就不管了,后面还有可以匹配的,对于判重的问题直接使用map就完事了,每次将转换后的标记为1,map[str]=1, 后面再有转换的时候判断一下map[str]是否等于1,如果等于就直接跳过,如果不等于就将其加入容器并标记为1
这种题目其实并不难,但是要注意的细节太多了,下面是AC代码~
#include<iostream>
#include <queue>
#include <map>
using namespace std;
#define Max 50
string a,b;//将a转换为b
string org[Max],obj[Max];
typedef pair<string,int> Node; //当前的字符串和步数
int res;//保存结果
int n=1;//转换的次数
void trans(string str,vector<string> &t);//看看str 里面有没有需要转换的
void bfs();
map<string,int > f; //去重
int main()
{
cin>>a>>b;
while(cin>>org[n]>>obj[n])
{
n++;
}
n--;
bfs();
if(res==-1)
{
cout<<"NO ANSWER!"<<endl;
} else
{
cout<<res<<endl;
}
return 0;
}
void bfs()
{
Node node;
node.first=a;
node.second=0;
queue<Node> t;
t.push(node);
while(!t.empty())
{
Node temp=t.front();
t.pop();
if(temp.first==b&&temp.second<=10)
{
res=temp.second;
return ;
}
else if(temp.second>10)
{
res=-1;
return ;
}
else
{
vector<string > vec;
trans(temp.first,vec);
for(vector<string>::iterator it=vec.begin();it!=vec.end();it++)
{
node.first=*it;
node.second=temp.second+1;
t.push(node);
}
if(t.empty()) //如果加入后队列仍然然为空,说明其变化在小于10步之前已经为空
{
res=-1;
return ;
}
}
}
}
void trans(string str,vector<string> &vec)//看看beq里面有没有需要转换的
{
vec.clear();
for(int i=1;i<=n;i++)
{
for(int j=0;j<=str.size()-1;j++)
{
string temp=str;
int nx=str.find(org[i],j);//从j号位置开始匹配
if(nx!=string::npos)
{
string t=temp.replace(nx,org[i].size(),obj[i]);//将nx开始的org[i].size()个字符替换成obj[i]
if(f[t]==0) //剪枝
{
vec.push_back(t);
f[t]=1;
}
}
}
}
return ;
}