BZOJ 1055 [HAOI2008]玩具取名

时间:2021-09-06 19:56:26

1055: [HAOI2008]玩具取名

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1119  Solved: 653
[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

Source

题解:区间DP嘛,L~R用a组可不可以,每次用字典来分割区间。

又因为没有解的情况WA了一发= =。。。。。。。。

 #include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstring>
#define PAU putchar(' ')
#define ENT putchar('\n')
using namespace std;
const int maxn=+,inf=-1u>>;
int id(char ch){
if(ch=='W')return ;
if(ch=='I')return ;
if(ch=='N')return ;
if(ch=='G')return ;
return -;
}
void princ(int a){
if(!a)putchar('W');
else if(a==)putchar('I');
else if(a==)putchar('N');
else if(a==)putchar('G');
return;
}
int t[],tx[][][],arr[maxn];int dp[][maxn][maxn];
bool solve(int a,int L,int R){
int&res=dp[a][L][R];if(res!=-)return res;
if(L==R)return (res=(arr[L]==a));
for(int i=L;i<R;i++){
for(int j=;j<t[a];j++){
if(solve(tx[a][j][],L,i)&&solve(tx[a][j][],i+,R))return (res=true);
}
}return (res=false);
}
inline int read(){
int x=;bool sig=;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=;
for(;isdigit(ch);ch=getchar())x=*x+ch-'';
return sig?x:-x;
}
inline void write(int x){
if(x==){putchar('');return;}if(x<)putchar('-'),x=-x;
int len=,buf[];while(x)buf[len++]=x%,x/=;
for(int i=len-;i>=;i--)putchar(buf[i]+'');return;
}
char s[maxn];
int main(){
for(int i=;i<;i++)t[i]=read();
for(int i=;i<;i++){
for(int j=;j<t[i];j++){
scanf("%s",s);tx[i][j][]=id(s[]);tx[i][j][]=id(s[]);
}
}
scanf("%s",s);
for(int i=;s[i];i++)arr[i]=id(s[i]);int Len=strlen(s);
memset(dp,-,sizeof(dp));bool flag=false;
for(int i=;i<;i++){
if(solve(i,,Len-))princ(i),flag=true;
}
if(!flag)puts("The name is wrong!");
return ;
}