dp[i][j][c],dp1[i][j][c]子串[l,r]能否完全变成c
vv1[l][c],vv2[l][c]从l开始的能完全变成c的所有r
ans[i][j],ss串的前i个字母和tt串的前j个字母的最短祖先
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int N=60;
char ss[N],tt[N];
int dp[N][N][30];
int dp1[N][N][30];
vector<int> vv[30];
vector<int> vv1[N][30],vv2[N][30];
void init(){
for(int i=0;i<26;i++)vv[i].clear();
for(int i=0;i<50;i++){
for(int j=0;j<26;j++){
vv1[i][j].clear();
vv2[i][j].clear();
}
}
}
int ans[N][N];
int main(){
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%s%s",&ss,&tt)!=EOF){
init();
int n;scanf("%d",&n);
for(int i=0;i<n;i++){
char tmp[10];scanf("%s",tmp);
vv[tmp[0]-'a'].push_back(tmp[3]-'a');
vv[tmp[0]-'a'].push_back(tmp[4]-'a');
}
int ls=strlen(ss),lt=strlen(tt);
memset(dp,0,sizeof(dp));
for(int i=ls-1;i>=0;i--){
dp[i][i][ss[i]-'a']=1;
vv1[i][ss[i]-'a'].push_back(i);
for(int j=i+1;j<ls;j++){
for(int c=0;c<26;c++){
int ed=vv[c].size();
int flag=0;
for(int x=0;x<ed&&!flag;x+=2){
int a=vv[c][x],b=vv[c][x+1];
for(int k=i;k<j;k++){
if(dp[i][k][a]&&dp[k+1][j][b]){
flag=1;break;
}
}
}
dp[i][j][c]=flag;
if(flag){
vv1[i][c].push_back(j);
}
}
}
}
memset(dp1,0,sizeof(dp1));
for(int i=lt-1;i>=0;i--){
dp1[i][i][tt[i]-'a']=1;
vv2[i][tt[i]-'a'].push_back(i);
for(int j=i+1;j<lt;j++){
for(int c=0;c<26;c++){
int ed=vv[c].size();
int flag=0;
for(int x=0;x<ed&&!flag;x+=2){
int a=vv[c][x],b=vv[c][x+1];
for(int k=i;k<j;k++){
if(dp1[i][k][a]&&dp1[k+1][j][b]){
flag=1;break;
}
}
}
dp1[i][j][c]=flag;
if(flag){
vv2[i][c].push_back(j);
}
}
}
}
memset(ans,-1,sizeof(ans));
for(int c=0;c<26;c++){
int ed1=vv1[0][c].size();
int ed2=vv2[0][c].size();
for(int x=0;x<ed1;x++){
for(int y=0;y<ed2;y++){
int a=vv1[0][c][x];
int b=vv2[0][c][y];
ans[a][b]=1;
}
}
}
for(int i=0;i<ls-1;i++){
for(int j=0;j<lt-1;j++)if(ans[i][j]!=-1){
for(int c=0;c<26;c++){
int ed1=vv1[i+1][c].size();
int ed2=vv2[j+1][c].size();
for(int x=0;x<ed1;x++){
for(int y=0;y<ed2;y++){
int a=vv1[i+1][c][x];
int b=vv2[j+1][c][y];
if(ans[a][b]==-1){
ans[a][b]=ans[i][j]+1;
}
else {
ans[a][b]=min(ans[a][b],ans[i][j]+1);
}
}
}
}
}
}
printf("%d\n",ans[ls-1][lt-1]);
}
return 0;
}