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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

洛谷——P1019 单词接龙

發(fā)布時(shí)間:2024/2/28 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷——P1019 单词接龙 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目描述

單詞接龍是一個(gè)與我們經(jīng)常玩的成語(yǔ)接龍相類似的游戲,現(xiàn)在我們已知一組單詞,且給定一個(gè)開(kāi)頭的字母,要求出以這個(gè)字母開(kāi)頭的最長(zhǎng)的“龍”(每個(gè)單詞都最多在“龍”中出現(xiàn)兩次),在兩個(gè)單詞相連時(shí),其重合部分合為一部分,例如?beastbeast和astonishastonish,如果接成一條龍則變?yōu)閎eastonishbeastonish,另外相鄰的兩部分不能存在包含關(guān)系,例如atat?和?atideatide?間不能相連。

輸入輸出格式

輸入格式:

?

輸入的第一行為一個(gè)單獨(dú)的整數(shù)nn?(n \le 20n≤20)表示單詞數(shù),以下nn?行每行有一個(gè)單詞,輸入的最后一行為一個(gè)單個(gè)字符,表示“龍”開(kāi)頭的字母。你可以假定以此字母開(kāi)頭的“龍”一定存在.

?

輸出格式:

?

只需輸出以此字母開(kāi)頭的最長(zhǎng)的“龍”的長(zhǎng)度

?

輸入輸出樣例

輸入樣例#1:?復(fù)制

5 at touch cheat choose tact a

輸出樣例#1:?復(fù)制

23

說(shuō)明

(連成的“龍”為atoucheatactactouchoose)

NOIp2000提高組第三題

作者:?Hinanawi_Feng

#include<cstdio> #include<iostream> #include<string> #include<cmath> using namespace std; int n;//單詞數(shù) string tr[30];//存儲(chǔ)字符串 int yc[30][30];//兩個(gè)字母的最小重疊部分 int vis[30];//判斷單詞使用頻率. int mt(int x, int y) //mt函數(shù),返回x單詞后連接一個(gè)y單詞的最小重疊部分 {bool pp = true;int ky = 0;for(int k = tr[x].size() - 1; k >= 0; k--) //要比較size次,從x單詞尾部向前看看最小重疊部分是從哪里開(kāi)始的,以為因?yàn)槭堑怪鴣?lái),所以保證是最小的{for(int kx = k; kx < tr[x].size(); kx++){if(tr[x][kx] != tr[y][ky++]){pp = false;break;}}if(pp == true) //如果說(shuō)當(dāng)前以k為開(kāi)頭的前一個(gè)單詞后綴 ,是后面單詞的前綴,就馬上返回重疊部分。(tr[x].size()-k是找出來(lái)的規(guī)律){return tr[x].size() - k;}ky = 0;pp = true; //不行就繼續(xù)}return 0; }//可能這里有點(diǎn)難理解。可以手動(dòng)模擬一下char ch;//開(kāi)頭字母 int ans = -1; //答案 int an = 0; //每次搜到的當(dāng)前最長(zhǎng)串void dfs(int p) //p為尾部單詞編號(hào)(p的后綴就是“龍”的后綴,因?yàn)閜已經(jīng)連接到”龍“后面了) {bool jx = false;for(int j = 1; j <= n; j++){if(vis[j] >= 2)continue;//使用了兩次就跳過(guò)if(yc[p][j] == 0)continue;//兩單詞之間沒(méi)有重合部分就跳過(guò)if(yc[p][j] == tr[p].size() || yc[p][j] == tr[j].size())continue;//兩者存在包含關(guān)系就跳過(guò)an += tr[j].size() - yc[p][j]; //兩單詞合并再減去最小重合部分vis[j]++;//使用了一次jx = true; //標(biāo)記一下當(dāng)前已經(jīng)成功匹配到一個(gè)可以連接的部分dfs(j); //接上去an -= tr[j].size() - yc[p][j]; //回溯,就要再減回去那一部分長(zhǎng)度vis[j]--;//回溯,使用--}if(jx == false) //jx==false說(shuō)明不能再找到任何一個(gè)單詞可以相連了{(lán)ans = max(ans, an); //更新ans}return; }int main() {scanf("%d", &n);for(int i = 1; i <= n; i++)cin >> tr[i];cin >> ch;for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){yc[i][j] = mt(i, j);}}//預(yù)處理yc數(shù)組。yc[i][j]就表示,i單詞后連接一個(gè)j單詞的最小重疊部分//比如 i表示at,j表示att. yc[i][j]就為2 但是yc[j][i]就為0.//預(yù)處理是一個(gè)關(guān)鍵for(int i = 1; i <= n; i++) //從頭到尾看一下有沒(méi)有以指定開(kāi)頭字母為開(kāi)頭的單詞{if(tr[i][0] == ch) //如果有,就以當(dāng)前單詞為基準(zhǔn)進(jìn)行搜索。{vis[i]++;//使用過(guò)一次an = tr[i].size(); //更新當(dāng)前串長(zhǎng)度dfs(i);//接上vis[i] = 0; //消除影響}}printf("%d", ans);return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的洛谷——P1019 单词接龙的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。