蒟蒻的第一道洛谷绿题,太菜了
题意很明显,知道算裸bfs,但是仔细想,蒟蒻表示很多难以下手。
1.如何去输入
2.如何去改变字符串
3.如何去存字符串
4.如何去标记已经出现的字符串//就像标记图中点一样
这是蒟蒻只有去求助题解了,耻辱了
针对上面问题一一解答
1.平时我们做的题,可能会输入一个n来代表输入的组数,而这里没有,然后看dalao博客才知道这样去输入,彻底刷新我的三观。
int n;//代表输入组数,方便以后用
string a,b;
cin>>a>>b;
while(cin>>ar[i]>>br[i]) n++;
这种输入肯定是不支持调试的,所以我调试的时候增加一个n,用for循环进行输入。
2.如何去改变字符串呢,dalao纷纷各显神通,有的手写函数,然而我发现有些dalao 用了 STL中的函数 。
str.substr(pos,l)//返回从str的pos位置开始寻找长度为l的字符串
str.replace(pos,l,a)//返回将str的pos,pos+l-1之间的字符串替换为字符串a
#include<bits/stdc++.h>
using namespace std;
int main()
{
string a="ChinaNO.1";
string b="niubu";
string c,d;
c=a.substr(0,5);
d=a.replace(5,4,b);
cout<<c<<"\n";//China
cout<<d<<"\n";//Chinaniubi
cout<<a;//Chinaniubi
}
这里需要注意的是,replace函数是将原字符串改变后返回,所以输出a时,和d是一样的,这个坑害了我好久,因为不会用这个函数,在改变字符串的时候,同时改变了frong 字符串,然后就错了。
3.如何去存字符串,无疑 string
struct node{
string str;//当前字符串
int step;//步数
};
4.如何去标记已经出现的字符串呢
又一个未知领域出现了,平时我们用 int 数组 来标记 。
但是这次是 字符串,一个 map 就横空出世了
map<string ,int > vis;
//这是我们这题用的map 类型,其实可以自己定义用很多种
vis 是指向 string 的map
map 重载了[]
所以是可以用数组的形式来表示的
但string a 出现后
vis[a]=1;
必备的知识都介绍完后,直接上代码吧,难点我会进行注释。
#include<bits/stdc++.h>
using namespace std;
int n;
string a,b;
string ar[12],br[12];
struct node{
string str;
int step;
};
queue<node> que;
map<string,bool> vis;
int bfs()
{
node st;
vis[a]=1;
st.str=a;
st.step=0;
while(!que.empty()) que.pop();
que.push(st);
while(!que.empty())
{
node front=que.front();
que.pop();
if(front.str==b)
{
printf("%d",front.step);
return 0;
}
if(front.step>10)
{
printf("NO ANSWER!\n");
return 0;
}
for(int i=0;i<n;i++)//n种变换方式
{
for(int j=0;j<front.str.size();j++)//变换位置
{
if(front.str.substr(j,ar[i].size())==ar[i])
{//发现子串 ar[i]
node tmp;
tmp.str=front.str;//以免造成 front.str的改变
tmp.str=tmp.str.replace(j,ar[i].size(),br[i]);
if(!vis[tmp.str])//没有出现过
{
vis[tmp.str]=1;
tmp.step=front.step+1;
que.push(tmp);
}
}
}
}
}
printf("NO ANSWER!\n");//十步以内也无法变成 b
}
int main()
{
cin>>a>>b;
while(cin>>ar[n]>>br[n]) n++;
bfs();
return 0;
}
来源:CSDN
作者:卑微求AC
链接:https://blog.csdn.net/ACMjiayou/article/details/104533030