QQ联系我

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;
}
posted @ 2017-10-25 16:39  czy020202  阅读(139)  评论(0编辑  收藏  举报