主要运用的是子字符串的替换和hash
关于子字符串的替换:一开始我用的是数组,2000多字,写的头大。正解应该用string和replace函数,非常方便!
hash:找一个合适的hash函数,然后构建hash表即可。
下方的代码可以在tyvj上ac。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
string a,b,usea[7],useb[7],st[10007];int cnt=1,hcnt=0;
int heade[10007],nexte[10007];
struct node{
string s;
int step;
};
queue<node> q;
int hashment(string s)
{
int k=0;
for(int i=0;i<=s.size();++i)
{
k=abs((k*33+s[i])%10007);
}
int n=heade[k];
while(n!=0)
{
if(st[n]==s) return 1;
else n=nexte[n];
}
nexte[++hcnt]=heade[k];
heade[k]=hcnt;
st[hcnt]=s;
return 0;
}
int main()
{
cin>>a;
cin>>b;
while(cin>>usea[cnt]>>useb[cnt])
{
cnt++;
}
q.push((node){a,0});
while(q.size()>0)
{
node t=q.front();q.pop();
if(t.s==b)
{
cout<<t.step;
return 0;
}
if(t.step==10) continue;
for(int i=1;i<=cnt;++i)
{
for(int j=0;j<=t.s.size()-1;++j)
{
if(j+usea[i].size()>t.s.size())
break;
if(t.s[j]==usea[i][0])
{
bool ok=1;
for(int k=1;k<=usea[i].size()-1;++k)
{
if(t.s[j+k]!=usea[i][k])
{
ok=0;
break;
}
}
if(ok)
{
string k1=t.s;
k1=k1.replace(j,usea[i].size(),useb[i],0,useb[i].size());
if(hashment(k1)==0)
{
q.push((node){k1,t.step+1});
}
}
}
}
}
}
cout<<"NO ANSWER!";
return 0;
}