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;
}

浙公网安备 33010602011771号