• 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("
    ");
    	return 0;
    }
  • 相关阅读:
    用同余理解补码
    objenesis
    spring 事务处理
    SOCKS5 协议解析
    WebSocket 的鉴权授权方案
    加密解密基础问题:字节数组和16进制字符串的相互转换
    主机字节序 与 网络字节序
    RSA 理论
    分类算法----k近邻算法
    R语言统计分析应用与SAS、SPSS的比较
  • 原文地址:https://www.cnblogs.com/chezhongyang/p/7729677.html
Copyright © 2020-2023  润新知