• BZOJ1055: [HAOI2008]玩具取名


    1055: [HAOI2008]玩具取名

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 820  Solved: 482
    [Submit][Status]

    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 [数据范围] 30%数据满足Len<=20,W、I、N、G<=6 100%数据满足Len<=200,W、I、N、G<=16

    Source

    题解:

    真是一道巧妙的DP!!!

    OI不是考你会不会什么算法,而是看你能不能想到。真正的大牛不会因为不会码什么而不会做什么题,什么算法都随便写,只要想到。。。

    这题如果有DP的想法就很简单了,dp[i][j][k]表示从 i 到 j 能否变成 k,然后就很好转移了。

    OI就应该多考这种思路巧妙而代码量又不大的题目!!!

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 300+100
    14 #define maxm 500+100
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 using namespace std;
    22 const char t[5]={' ','W','I','N','G'};
    23 inline int read()
    24 {
    25     int x=0,f=1;char ch=getchar();
    26     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    27     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    28     return x*f;
    29 }
    30 vector<int> a[5][5];
    31 int num[5],n,ans;
    32 bool dp[maxn][maxn][5];
    33 string s;
    34 inline int hash(char ch)
    35 {
    36     if(ch=='W')return 1;
    37     if(ch=='I')return 2;
    38     if(ch=='N')return 3;
    39     if(ch=='G')return 4;    
    40 }
    41 int main()
    42 {
    43     freopen("input.txt","r",stdin);
    44     freopen("output.txt","w",stdout);
    45     for1(i,4)num[i]=read();
    46     for1(i,4)
    47      for1(j,num[i])
    48       {
    49           cin>>s;
    50           a[hash(s[0])][hash(s[1])].push_back(i);
    51       }
    52     cin>>s;
    53     n=s.length();
    54     for1(i,n)dp[i][i][hash(s[i-1])]=1;  
    55     for2(l,2,n)
    56      for1(i,n-l+1)
    57       {
    58           int j=i+l-1;
    59           for2(k,i,j-1)
    60           for1(p,4)
    61            if(dp[i][k][p])
    62             for1(q,4)
    63              if(dp[k+1][j][q])
    64               for(int w=0;w<a[p][q].size();w++)
    65                dp[i][j][a[p][q][w]]=1;
    66       }
    67     ans=0;
    68     for1(i,4)if(dp[1][n][i])ans++,cout<<t[i];
    69     if(!ans)puts("The name is wrong!");  
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    LeetCode中等题(三)
    java之使用poi对excel的.xls和.xlsx访问
    JAVA编程-----------40、字符串排序
    JAVA编程------------38、写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度
    JAVA编程---------37、n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡是报到3的人退出圈子,问最后留下的是原来第几号的那位。
    JAVA编程--------------36、有n个整数,使其前面各数顺序向后移m个位置最后m个数变成前面m个数
    JAVA编程-------------24、将一组数的最大数放在第一位,最小的数放在最后一位
    JAVA编程------------33、打印杨辉三角
    JAVA编程--------------32、取一个整数的4-7位
    JAVA编程---------------31、将一个数组逆序输出
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3961149.html
Copyright © 2020-2023  润新知