Codeforces 49E

来源:互联网 发布:编程代码有几种 编辑:程序博客网 时间:2024/06/10 01:43

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;}
0 0
原创粉丝点击