[HAOI2008]玩具取名
[HAOI2008]玩具取名
文章目錄
- 題目描述
- 輸出描述:
- 題解
- 代碼:
題目描述
某人有一套玩具,并想法給玩具命名。首先他選擇WING四個字母中的任意一個字母作為玩具的基本名字。然后他會根據自己的喜好,將名字中任意一個字母用“WING”中任意兩個字母代替,使得自己的名字能夠擴充得很長。
現在,他想請你猜猜某一個很長的名字,最初可能是由哪幾個字母變形過來的。 輸入描述:
第一行四個整數W、I、N、G。表示每一個字母能由幾種兩個字母所替代。 接下來W行,每行兩個字母,表示W可以用這兩個字母替代。
接下來I行,每行兩個字母,表示I可以用這兩個字母替代。 接下來N行,每行兩個字母,表示N可以用這兩個字母替代。
接下來G行,每行兩個字母,表示G可以用這兩個字母替代。 最后一行一個長度不超過Len的字符串。表示這個玩具的名字。
輸出描述:
一行字符串,該名字可能由哪些字母變形而得到。(按照WING的順序輸出) 如果給的名字不能由任何一個字母變形而得到則輸出“The name
is wrong!”
示例1
輸入
輸出
IN題解
題目雖然輸入的是字母,但是我們可以當做數字來處理
重要的兩個數組,均為bool型
dp[i][j][k]表示區間[i,j]是否是由k轉化而來的
can[i][j][k]表示i是否可以用 j k 兩個字母代替
can是在讀入時更新
我們想一想區間更新的條件:
區間[l,r],中間點為k
z,z1,z2為1~4,表示為WING
如果左區間[l,k+1]可以由z1轉化(即代碼dp[l][k][z1]),右區間[k+1,r]可以由z2轉化(代碼dp[k+1][r][z2]),
z可以用z1和z2來代替(代碼dp[z][z1][z2]),那是不是就說明區間[l,r]是由z轉化的
(相當于z1,z2是一個中轉站,用來將區間[l,r]與z聯系在一起)
套上區間dp的萬能模板
就能得到
代碼:
#include<bits/stdc++.h> using namespace std; const int maxn=3e2+7; int dp[maxn][maxn][maxn]; bool can[maxn][maxn][maxn]; int p[maxn]; char s[maxn]; int a[300]; int change(char i){ if(i=='W') return 1; if(i=='I') return 2;if(i=='N') return 3; if(i=='G') return 4; } int main() {a['W']=1;a['I']=2;a['N']=3;a['G']=4;for(int i=1;i<=4;i++)cin>>p[i];for(int i=1;i<=4;i++){for(int j=1;j<=p[i];j++){char x,y;cin>>x>>y;can[i][a[x]][a[y]]=1;}}cin>>(s+1);int n=strlen(s+1); // cout<<n<<endl; for(int i=1;i<=n;i++)dp[i][i][a[s[i]]]=1;for(int len=2;len<=n;len++){for(int i=1;i<=n;i++){int j=i+len-1;if(j>n)break;for(int k=i;k<=j;k++){for(int z=1;z<=4;z++){for(int z1=1;z1<=4;z1++){for(int z2=1;z2<=4;z2++){if(can[z][z1][z2]&&dp[i][k][z1]&&dp[k+1][j][z2])dp[i][j][z]=1;}}}}}}bool flag=false;if(dp[1][n][1]) {flag=true;printf("W");}if(dp[1][n][2]) {flag=true;printf("I");}if(dp[1][n][3]) {flag=true;printf("N");}if(dp[1][n][4]) {flag=true;printf("G");}if(!flag) printf("The name is wrong!"); }總結
以上是生活随笔為你收集整理的[HAOI2008]玩具取名的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 想买个家用的路由器无线路由器怎么选择
- 下一篇: [HAOI2016]字符合并(ing)