题目描述
已知有两个字串 A,BA,B 及一组字串变换的规则(至多 66 个规则):
A_1A1 -> B_1B1
A_2A2 -> B_2B2
规则的含义为:在 AA 中的子串 A_1A1 可以变换为 B_1B1 , A_2A2 可以变换为 B_2B2 …。
例如: AA =' abcdabcd ' BB =' xyzxyz '
变换规则为:
‘ abcabc ’->‘ xuxu ’‘ udud ’->‘ yy ’‘ yy ’->‘ yzyz ’
则此时, AA 可以经过一系列的变换变为 BB ,其变换的过程为:
‘ abcdabcd ’->‘ xudxud ’->‘ xyxy ’->‘ xyzxyz ’
共进行了 33 次变换,使得 AA 变换为 BB 。
输入输出格式
输入格式:
输入格式如下:
AA BB
A_1A1 B_1B1
A_2A2 B_2B2 |-> 变换规则
... ... /
所有字符串长度的上限为 2020 。
输出格式:
输出至屏幕。格式如下:
若在 1010 步(包含 1010 步)以内能将 AA 变换为 BB ,则输出最少的变换步数;否则输出"NO ANSWER!"
输入输出样例
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100000
using namespace std;
int n=1,ans=0x7f7f7f7f;
string A,B;
int net[MAXN],vis[MAXN];
struct nond{
string s1,s2;
}v[7];
int judge(string sa,string sb){
int len1=sa.length();
if(len1!=sb.length()) return 0;
else for(int i=0;i<len1;i++)
if(sa[i]!=sb[i]) return 0;
return 1;
}
void getnet(string p){
int plen=p.length();
net[0]=-1;
int k=-1;
int j=0;
while(j<plen){
if(k==-1||p[j]==p[k]){
j++;k++;
net[j]=k;
}
else k=net[k];
}
}
int kmp(string s,string p){
getnet(p);
int i=0,j=0;
int slen=s.length();
int plen=p.length();
while(i<slen){
if(j==-1||s[i]==p[j]){
i++;j++;
}
else j=net[j];
if(j==plen){
return i-plen;
j=0,i--;
}
}
return -1;
}
void dfs(int tot,string s){
if(tot==10) return ;
if(judge(s,B)==1){
ans=min(ans,tot);
return ;
}
for(int i=1;i<=n;i++)
if(vis[i]<=2){
//memset(net,0,sizeof(net));
int l1=s.length(),l2=v[i].s1.length();
int be=kmp(s,v[i].s1);
if(be!=-1){
string s3;vis[i]++;
for(int j=0;j<be;j++) s3+=s[j];
s3+=v[i].s2;
for(int j=be+l2;j<l1;j++) s3+=s[j];
dfs(tot+1,s3);vis[i]--;
}
}
}
int main(){
cin>>A>>B;
while(cin>>v[n].s1>>v[n].s2){
n++;
if(n==7) break;
}
n--;
dfs(0,A);
if(ans==0x7f7f7f7f) cout<<"NO ANSWER!"<<endl;
else cout<<ans;
}
#include<map> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #define maxn 15 using namespace std; struct node{ string str; int step; }; string a,b; string orginal[maxn]; string translated[maxn]; int n,ans; map<string,int>ma; string trans(const string &str,int i,int j){ string ans=""; if(i+orginal[j].length()>str.length()) return ans; for (int k=0;k<orginal[j].length();k++) if (str[i+k]!=orginal[j][k]) return ans; ans=str.substr(0,i); ans+=translated[j]; ans+=str.substr(i+orginal[j].length()); return ans; } void bfs(){ queue<node>q; node s; s.str=a; s.step=0; q.push(s); while(!q.empty()){ node u=q.front(); q.pop(); string temp; if(ma.count(u.str) == 1) continue; if(u.str==b){ ans=u.step; break; } ma[u.str] = 1; for (int i=0;i<u.str.length();i++) for (int j=0;j<n;j++){ temp=trans(u.str,i,j); if(temp!=""){ node v; v.str=temp; v.step=u.step+1; q.push(v); } } } if(ans>10||ans==0) cout<<"NO ANSWER!"<<endl; else cout<<ans<<endl; } int main(){ cin>>a>>b; while(cin>>orginal[n]>>translated[n]) n++; bfs(); return 0; }