日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[HAOI2008]玩具取名

發布時間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [HAOI2008]玩具取名 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[HAOI2008]玩具取名

文章目錄

    • 題目描述
    • 輸出描述:
    • 題解
    • 代碼:

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld

題目描述

某人有一套玩具,并想法給玩具命名。首先他選擇WING四個字母中的任意一個字母作為玩具的基本名字。然后他會根據自己的喜好,將名字中任意一個字母用“WING”中任意兩個字母代替,使得自己的名字能夠擴充得很長。
現在,他想請你猜猜某一個很長的名字,最初可能是由哪幾個字母變形過來的。 輸入描述:
第一行四個整數W、I、N、G。表示每一個字母能由幾種兩個字母所替代。 接下來W行,每行兩個字母,表示W可以用這兩個字母替代。
接下來I行,每行兩個字母,表示I可以用這兩個字母替代。 接下來N行,每行兩個字母,表示N可以用這兩個字母替代。
接下來G行,每行兩個字母,表示G可以用這兩個字母替代。 最后一行一個長度不超過Len的字符串。表示這個玩具的名字。

輸出描述:

一行字符串,該名字可能由哪些字母變形而得到。(按照WING的順序輸出) 如果給的名字不能由任何一個字母變形而得到則輸出“The name
is wrong!”

示例1
輸入

1 1 1 1 II WW WW IG IIII

輸出

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的萬能模板
就能得到

for(int i=1;i<=len;i++) dp[i][i][a[i]]=true;//從i到i可以由他自己轉化for(int led=1;led<len;led++)//列舉長度的可能性for(int l=1;l<=len-led;l++)//列舉左界的可能性 {int r=l+led;//右界可以算出來for(int k=l;k<r;k++) //在左右之間列舉可能的斷點 for(int z=1;z<=4;z++) //列舉l到r(需要的區間)可能轉化成的字母for(int z1=1;z1<=4;z1++) // 列舉l到k(借助的左區間)for(int z2=1;z2<=4;z2++) //列舉k + 1到r(借助的右區間)if(can[z][z1][z2] && dp[l][k][z1] && dp[k+1][r][z2]) //如果z1、z2可以轉化成z 并且 l到k可以變成z1 并且k+1到r可以變成z2dp[l][r][z]=true; //那么l到r就可以轉化成z}

代碼:

#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]玩具取名的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。