题目描述
这道题实际上就是给你一个字符串,然后给你一些变换规则,问最小需要多少步数可以到达最终的那个字符串;
这道题呢,实际上是不应该用STL的,因为毕竟2011年STL才解禁,于是写了一个hash来代替set,目的是使一个子串不重复进队(但考虑到队列不好实现,便没有手写队列)
直接上代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod1=16927;
const int mod2=998244353;
queue <string> q;
queue <int> cnt;
const int N=6+5;
string a[N];
string b[N];
string s;
string t;
int n;
struct node
{
int k1;
string s;
node(int kk1,string ss)
{
k1=kk1;
s=ss;
}
node() {};
};
vector <node> v[mod1];
int get_hash_key(const string &letter,const int &mod)
{
int ans=0;
int len=letter.length();
for (int i=0; i<len; i++)
ans=(ans*131+letter[i])%mod;
return ans;
}
int find(const string &w)
{
int key1=get_hash_key(w,mod1);
for (int i=0; i<v[key1].size(); i++)
{
if (v[key1][i].s==w)
{
return 1;
}
}
return 0;
}
void insert(const string &w)
{
int key1=get_hash_key(w,mod1);
for (int i=0; i<v[key1].size(); i++)
{
if (v[key1][i].s==w)
{
break;
}
}
v[key1].push_back(node(key1,w));
return;
}
int bfs()
{
q.push(s);
cnt.push(0);
while (!q.empty())
{
string now=q.front();
int count=cnt.front();
if (count==10)
return -1;
q.pop();
cnt.pop();
for (int i=0; i<n; i++)
{
int len=now.length();
for (int j=0; j<len - (int)a[i].length() + 1; j++)
{
bool flag=1;
for (int k=0; k<(int)a[i].length(); k++)
{
if (now[j + k] != a[i][k])
{
flag = 0;
break;
}
}
if (flag)
{
string New;
for (int k = 0; k < j; k++) New += now[k];
New += b[i];
for (int k = j + a[i].length(); k < len; k++) New += now[k];
if (New == t) return count + 1;
if (find(New))
continue;
insert(New);
q.push(New);
cnt.push(count+1);
}
}
}
}
return -1;
}
int main()
{
cin>>s>>t;
for (n=0; cin>>a[n]>>b[n]; n++);
int ans=bfs();
if (ans==-1)
printf("NO ANSWER!\n");
else
printf("%d\n",ans);
return 0;
}