zoukankan      html  css  js  c++  java
  • bzoj1055 [HAOI2008]玩具取名

    [HAOI2008]玩具取名

    Time Limit: 10 Sec Memory Limit: 162 MB

    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

    来简单说说这道题对我的意义:
    1.联系了一波区间动归的基本操作。
    2.设状态嘛,大胆设,不存在的,for循环嘛
    3.有点码农啊(笑嘻嘻的我~)

    (dp[i][j][k]) 表示区间dp的状态,我们要求出[i, j]区间可以生成的字母,四个字母分别用1,2,3,4来表示就好了。。。
    这道题太tm暴力了~

    
    #include<bits/stdc++.h>
    using namespace std;
    bool dp[205][205][5];
    bool flag[205][205];
    int W, I, N, G, len;
    char s[205], ww[20][3], ii[20][3], nn[20][3], gg[20][3];
    
    inline void putit()
    {
    	scanf("%d%d%d%d", &W, &I, &N, &G);
    	for(int i = 1; i <= W; ++i) scanf("%s", ww[i] + 1);
    	for(int i = 1; i <= I; ++i) scanf("%s", ii[i] + 1);
    	for(int i = 1; i <= N; ++i) scanf("%s", nn[i] + 1);
    	for(int i = 1; i <= G; ++i) scanf("%s", gg[i] + 1);	
    	scanf("%s", s + 1);  len = strlen(s + 1);
    }
    
    inline void prepare()
    {
    	for(int i = 1; i < len; ++i) 
    	{
    		for(int j = 1; j <= W; ++j) 
    			if(ww[j][1] == s[i] && ww[j][2] == s[i + 1]) 
    				{dp[i][i + 1][1] = true; break;}
    		for(int j = 1; j <= I; ++j) 
    			if(ii[j][1] == s[i] && ii[j][2] == s[i + 1]) 
    				{dp[i][i + 1][2] = true; break;}
    		for(int j = 1; j <= N; ++j) 
    			if(nn[j][1] == s[i] && nn[j][2] == s[i + 1]) 
    				{dp[i][i + 1][3] = true; break;}
    		for(int j = 1; j <= G; ++j) 
    			if(gg[j][1] == s[i] && gg[j][2] == s[i + 1]) 
    				{dp[i][i + 1][4] = true; break;}
    		flag[i][i + 1] = true;
    	}
    	for(int i = 1; i <= len; ++i)
    	{
    		if(s[i] == 'W') {flag[i][i] = true; dp[i][i][1] = true; continue;}
    		if(s[i] == 'I') {flag[i][i] = true; dp[i][i][2] = true; continue;}
    		if(s[i] == 'N') {flag[i][i] = true; dp[i][i][3] = true; continue;}
    		if(s[i] == 'G') {flag[i][i] = true; dp[i][i][4] = true; continue;}
    	} 
    }
    
    inline int calc(char t)
    {
    	int ret;
    	if(t == 'W') ret = 1;
    	else if(t == 'I') ret = 2;
    	else if(t == 'N') ret = 3;
    	else if(t == 'G') ret = 4;
    	return ret;
    }
    
    inline void search1(int fl, int fr, int sl, int sr)
    {
    	for(int i = 1; i <= W; ++i)
    		if(dp[fl][fr][calc(ww[i][1])] && dp[sl][sr][calc(ww[i][2])]) {dp[fl][sr][1] = true; return;}
    }
    
    inline void search2(int fl, int fr, int sl, int sr)
    {
    	for(int i = 1; i <= I; ++i)
    		if(dp[fl][fr][calc(ii[i][1])] && dp[sl][sr][calc(ii[i][2])]) {dp[fl][sr][2] = true; return;}
    }
    
    inline void search3(int fl, int fr, int sl, int sr)
    {
    	for(int i = 1; i <= N; ++i)
    		if(dp[fl][fr][calc(nn[i][1])] && dp[sl][sr][calc(nn[i][2])]) {dp[fl][sr][3] = true; return;}
    }
    
    inline void search4(int fl, int fr, int sl, int sr)
    {
    	for(int i = 1; i <= W; ++i)
    		if(dp[fl][fr][calc(gg[i][1])] && dp[sl][sr][calc(gg[i][2])]) {dp[fl][sr][4] = true; return;}
    }
    
    void workk(int l, int r)
    {
    	if(flag[l][r]) return;
    	for(int i = l; i < r; ++i)
    	{
    		workk(l, i); workk(i + 1, r);
    		if(!dp[l][r][1]) search1(l, i, i + 1, r);
    		if(!dp[l][r][2]) search2(l, i, i + 1, r);
    		if(!dp[l][r][3]) search3(l, i, i + 1, r);
    		if(!dp[l][r][4]) search4(l, i, i + 1, r);
    	}
    	flag[l][r]= true; return;
    }
    
    int main()
    {
    	putit();
    	prepare();
    	workk(1, len);
    	if(dp[1][len][1]) cout << "W";
    	if(dp[1][len][2]) cout << "I";
    	if(dp[1][len][3]) cout << "N";
    	if(dp[1][len][4]) cout << "G";
    	if(!dp[1][len][1] && !dp[1][len][2] && !dp[1][len][3] && !dp[1][len][4]) cout << "The name is wrong!";
    	return 0;
    }
    
    
    心如花木,向阳而生。
  • 相关阅读:
    Android开发 使用 adb logcat 显示 Android 日志
    【嵌入式开发】向开发板中烧写Linux系统-型号S3C6410
    C语言 结构体相关 函数 指针 数组
    C语言 命令行参数 函数指针 gdb调试
    C语言 指针数组 多维数组
    Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
    C语言 内存分配 地址 指针 数组 参数 实例解析
    CRT 环境变量注意事项
    hadoop 输出文件 key val 分隔符
    com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Too many connections
  • 原文地址:https://www.cnblogs.com/LLppdd/p/8570009.html
Copyright © 2011-2022 走看看