BZOJ1055:HAOI2008玩具取名

Description

  某人有一套玩具,并想法给玩具命名。首先他选择WING四个字母中的任意一个字母作为玩具的基本名字。然后
他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够扩充得很长。
现在,他想请你猜猜某一个很长的名字,最初可能是由哪几个字母变形过来的。

Input

  第一行四个整数W、I、N、G。表示每一个字母能由几种两个字母所替代。接下来W行,每行两个字母,表示W可
以用这两个字母替代。接下来I行,每行两个字母,表示I可以用这两个字母替代。接下来N行,每行两个字母,表示N
可以用这两个字母替代。接下来G行,每行两个字母,表示G可以用这两个字母替代。最后一行一个长度不超过Len的
字符串。表示这个玩具的名字。

Output

  一行字符串,该名字可能由哪些字母变形而得到。(按照WING的顺序输出)如果给的名字不能由任何一个字母
变形而得到则输出“The name is wrong!”

Solution

    用布尔数组f[i][j][k]来表示i到j的这段区间内能否用k表示。用w存储输入数据,读入的第i组信息是N可转换为IG,那么w[i][1]储存I,w[i][2]储存G,w[i][3]则储存N。还是看程序注释吧。

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<string>
 7 using namespace std;
 8 bool f[222][222][5];
 9 int w[111][5],num;
10 string s;
11 int main()
12 { 
13     int a,b,c,d;
14     cin>>a>>b>>c>>d;
15     num=a+b+c+d;
16     for (int i=1; i<=a; i++) w[i][3]=1;//用1 2 3 4分别代表W I N G
17     for (int i=a+1; i<=a+b; i++) w[i][3]=2;
18     for (int i=a+b+1; i<=num-d; i++) w[i][3]=3;
19     for (int i=num-d+1; i<=num; i++) w[i][3]=4;
20     for (int i=1; i<=num; i++)
21     {
22         cin>>s;
23         switch (s[0])
24         {
25           case 'W':w[i][1]=1; break;
26           case 'I':w[i][1]=2; break;
27           case 'N':w[i][1]=3; break;
28           case 'G':w[i][1]=4; break;
29         }
30         switch (s[1])
31         {
32           case 'W':w[i][2]=1; break;
33           case 'I':w[i][2]=2; break;
34           case 'N':w[i][2]=3; break;
35           case 'G':w[i][2]=4; break;
36         }
37     } 
38     cin>>s;
39     int slen=s.size();
40     memset(f,false,sizeof(f));
41     for (int i=0; i<=slen-1; i++)
42       switch (s[i])
43       {
44         case 'W':f[i+1][i+1][1]=true; break;
45         case 'I':f[i+1][i+1][2]=true; break;
46         case 'N':f[i+1][i+1][3]=true; break;
47         case 'G':f[i+1][i+1][4]=true; break;
48       }
49     int r;  
50     for (int len=2; len<=slen; len++)
51       for (int l=1; l<=slen-len+1; l++)
52       {
53           r=l+len-1;
54           for (int m=l; m<=r-1; m++)
55             for (int k=1; k<=num; k++)
56               f[l][r][w[k][3]]=(f[l][m][w[k][1]])&&(f[m+1][r][w[k][2]])||(f[l][r][w[k][3]]);
57       }    
58     int ans=0;
59     bool fg=false;
60     for (int i=1; i<=4; i++)
61       if (f[1][slen][i])
62       { 
63           switch (i)
64           {
65             case 1: cout<<'W'; break;
66             case 2: cout<<'I'; break;
67             case 3: cout<<'N'; break;
68             case 4: cout<<'G'; break;
69         }
70         fg=true;
71       } 
72     if (fg==false) cout<<"The name is wrong!"<<endl;
73     return 0;
74 } 

 

posted @ 2017-02-06 11:50  xzy12138  阅读(271)  评论(0编辑  收藏  举报