题目传送门
我即使是死了,钉在棺材里了,也要在墓里,用这腐朽的声带喊出
STL大法好
这题最麻烦的其实是处理字符串,真正的搜索部分我个人认为也就只有橙题或黄题的难度。而处理字符串,正如前面所说,STL大法好!虽然也有好多人用了STL,但我个人认为我的更精巧一些(各位dalao不要打我 ~(>_<。)\ )
用STL实现替换是这样的:
string repl(int be,string x,string y,string z) //将字符串x从be位置开始的第一个子串y替换成z,如果子串y不被x包含,则返回x
{
int pos=x.find(y,be); //寻找子串y在x中的位置,如果不存在,返回-1
if(pos>=0) //如果y存在,则进行替换操作
x=x.replace(pos,y.size(),z); //将x在pos位置的长度为y.size的串(也就是y)替换成z
return x; //返回更改后的字符串
}
用STL实现的判重是这样的:
map <string,bool> vis;
这样再进行广搜寻找最优解就方便得多了。由于广搜实现起来很简单,就不单独解释了,直接上完整代码。
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
struct yyy{
string f,
t;
}rule[10]; //存变换规则
struct hhh{
string now;
int st;
}q[10001]; //模拟队列,now是当前的字串,st是步数
int h=1,t;
map<string,bool> vis; //map查重
string repl(int be,string x,string y,string z) //替换子串,前面已经讲过了
{
int pos=x.find(y,be);
if(pos>=0)
x=x.replace(pos,y.size(),z);
return x;
}
int main()
{
//输入
string a,b; int n=0;
cin>>a>>b;
while(cin>>rule[++n].f&&cin>>rule[n].t)
//搜索
q[++t].now=a;
vis[a]=1;
while(h<=t)
{
for(int i=1;i<=n;i++)
{
for(int j=0;j<q[h].now.size();j++)
{
string x=repl(j,q[h].now,rule[i].f,rule[i].t);
if(x==b)
{
cout<<q[h].st+1;
return 0;
}
if(!vis[x]&&q[h].st+1<=10)
{
vis[x]=1;
q[++t].now=x; q[t].st=q[h].st+1;
}
}
}
h++;
}
cout<<"NO ANSWER!";
return 0;
}