BZOJ 1055: [HAOI2008]玩具取名
1055: [HAOI2008]玩具取名
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2093 Solved: 1225
[Submit][Status][Discuss]
Description
某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。
Input
第一行四个整数W、I、N、G。表示每一个字母能由几种两个字母所替代。接下来W行,每行两个字母,表示W可以用这两个字母替代。接下来I行,每行两个字母,表示I可以用这两个字母替代。接下来N行,每行两个字母,表示N可以用这两个字母替代。接下来G行,每行两个字母,表示G可以用这两个字母替代。最后一行一个长度不超过Len的字符串。表示这个玩具的名字。
Output
一行字符串,该名字可能由哪些字母变形而得到。(按照WING的顺序输出)如果给的名字不能由任何一个字母变形而得到则输出“The name is wrong!”
Sample Input
1 1 1 1
II
WW
WW
IG
IIII
Sample Output
IN
HINT
W可以变成II所以IIII可以缩成WW IN均能变成WW所以WW又可以缩成I或者N 所以最终答案应该按照“WING”的顺序
输出IN
[数据范围]
100%数据满足Len<=200,W、I、N、G<=16
题解
区间DP,f[i][j][ch]表示i到j区间是否能合成字符ch,先枚举区间长度,再在i到j-1枚举k,判断区间(i,k)和区间(k+1,j)是否能合成ch字符的两个替代字母。
代码
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> using namespace std; const int N=205,M=20; int c[10],s[N],f[N][N][10]; int change(char a){ if(a=='W')return 1; if(a=='I')return 2; if(a=='N')return 3; if(a=='G')return 4; } struct node{ int a,b; }a[10][20]; int main(){ scanf("%d%d%d%d",&c[1],&c[2],&c[3],&c[4]); char ch[N]; for(int i=1;i<=c[1];i++){ scanf("%s",ch); a[1][i].a=change(ch[0]); a[1][i].b=change(ch[1]); } for(int i=1;i<=c[2];i++){ scanf("%s",ch); a[2][i].a=change(ch[0]); a[2][i].b=change(ch[1]); } for(int i=1;i<=c[3];i++){ scanf("%s",ch); a[3][i].a=change(ch[0]); a[3][i].b=change(ch[1]); } for(int i=1;i<=c[4];i++){ scanf("%s",ch); a[4][i].a=change(ch[0]); a[4][i].b=change(ch[1]); } scanf("%s",ch+1); int len=strlen(ch+1); for(int i=1;i<=len;i++){ s[i]=change(ch[i]); f[i][i][s[i]]=1; } for(int i=2;i<=len;i++){ for(int j=1;j+i-1<=len;j++){ for(int k=1;k<=4;k++){ for(int l=1;l<=c[k];l++){ for(int m=j;m<j+i-1;m++){ if(f[j][m][a[k][l].a]&&f[m+1][j+i-1][a[k][l].b]){ f[j][j+i-1][k]=1; break; } } if(f[j][j+i-1][k])break; } } } } int fg=0; if(f[1][len][1])fg=1,printf("W"); if(f[1][len][2])fg=1,printf("I"); if(f[1][len][3])fg=1,printf("N"); if(f[1][len][4])fg=1,printf("G"); if(!fg)printf("The name is wrong!"); printf("\n"); return 0; }