zoukankan      html  css  js  c++  java
  • BZOJ 1055 玩具取名

    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我又没有看出来,我是不是老了。。。。QAQ
    f[i][j][k]表示i到j这段区间是否可以合成字母k,然后就没有然后了,脑补吧!!!
     
     1 #include<cstring>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 using namespace std;
     5 
     6 #define maxn 210
     7 bool f[maxn][maxn][5];int n[5],vec[5][16];
     8 
     9 inline int change(char ch)
    10 {
    11     switch (ch)
    12     {
    13         case 'W': return 1; break;
    14         case 'I': return 2; break;
    15         case 'N': return 3; break;
    16         default: return 4; break;
    17     }
    18 }
    19 
    20 inline void dp()
    21 {
    22     char s[maxn]; scanf("%s",s+1); int l = strlen(s+1);
    23     for (int i = 1;i <= l;++i) f[i][i][change(s[i])] = true;
    24     for (int i = 2;i <= l;++i)
    25         for (int j = 1;j+i-1 <= l;++j)
    26             for (int k = 1;k <= 4;++k)
    27                 for (int p = 1;p <= n[k]&&!f[j][j+i-1][k];++p)
    28                     for (int q = j;q < j+i-1;++q)
    29                         if (f[j][q][vec[k][p]/10]&f[q+1][j+i-1][vec[k][p]%10])
    30                             { f[j][j+i-1][k] = true; break; }
    31     bool sign = false;
    32     for (int i = 1;i <= 4;++i)
    33         if (f[1][l][i])
    34         {
    35             sign = true;
    36             switch (i)
    37             {
    38                 case 1: putchar('W'); break;
    39                 case 2: putchar('I'); break;
    40                 case 3: putchar('N'); break;
    41                 default: putchar('G'); break; 
    42             }
    43         }
    44     if (!sign) printf("The name is wrong!");
    45 }
    46 
    47 int main()
    48 {
    49     freopen("1055.in","r",stdin);
    50     freopen("1055.out","w",stdout);
    51     for (int i = 1;i <= 4;++i) scanf("%d
    ",n+i);
    52     for (int i = 1;i <= 4;++i)
    53         for (int j = 1;j <= n[i];++j)
    54         {
    55             char opt[4]; scanf("%s",opt);
    56             int t = 10*change(opt[0])+change(opt[1]);
    57             vec[i][j] = t;
    58         }
    59     dp();
    60     fclose(stdin); fclose(stdout);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/mmlz/p/4297661.html
Copyright © 2011-2022 走看看