P1019 單詞接龍

題目描述

單詞接龍是一個與我們經常玩的成語接龍相類似的遊戲,現在我們已知一組單詞,且給定一個開頭的字母,要求出以這個字母開頭的最長的“龍”(每個單詞都最多在“龍”中出現兩次),在兩個單詞相連時,其重合部分合爲一部分,例如 beastbeastbeast和astonishastonishastonish,如果接成一條龍則變爲beastonishbeastonishbeastonish,另外相鄰的兩部分不能存在包含關係,例如atatat 和 atideatideatide 間不能相連。

輸入格式

輸入的第一行爲一個單獨的整數nnn (n≤20n \le 20n≤20)表示單詞數,以下nnn 行每行有一個單詞,輸入的最後一行爲一個單個字符,表示“龍”開頭的字母。你可以假定以此字母開頭的“龍”一定存在.

輸出格式

只需輸出以此字母開頭的最長的“龍”的長度

輸入輸出樣例

輸入 #1

5
at
touch
cheat
choose
tact
a

輸出 #1

23

說明/提示

(連成的“龍”爲atoucheatactactouchoose)

NOIp2000提高組第三題

題目大意:讀題吧。

解題思路:需要預處理出每兩個串之間前綴和後綴的公共長度是多少,然後從龍的第一個字母開始搜就可以了。

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef unsigned long long ull ;
typedef long long ll ;
const int Maxn = 50;
const int INF = 0x3f3f3f3f ;
const ull seed = 133 ;
const double PI =  acos(-1.0) ;

int con[Maxn][Maxn] ;
int vis[Maxn], ans, n ;
string s[Maxn] ,op ;

int check(int x, int y){
    int len1 = s[x].size() ;
    int len2 = s[y].size() ;
    for (int k = 1; k <= min(len1, len2); k++){
        int i = len1 - k ;
        int j = 0 ;
        bool flag = true ;
        while (i < len1 && j <= k){
            if (s[x][i] != s[y][j]) {
                flag = false ;
                break ;
            }
            i++ ;
            j++ ;
        }
        if (flag) return k;
    }
    return 0 ;
}

void init(){
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++){
            con[i][j] = check(i, j) ;
        }
    }
}

void Dfs(int index, int len){
    ans = max(ans, len) ;
    for (int i = 1; i <= n; i++){
        if (vis[i] > 1) continue ; // 每一個單詞只能用兩次
        if (con[index][i] == 0) continue ;
        vis[i]++ ;
        Dfs(i, len + s[i].size() - con[index][i]) ;
        vis[i]-- ;
    }
}

int main (){
    cin >> n ;
    for (int i = 1; i <= n; i++) cin >> s[i] ;
    cin >> op ;
    init() ;
    for (int i = 1; i <= n; i++){
        if (s[i][0] == op[0]){ // 從龍的相同字符開始搜起
            vis[i]++ ;
            Dfs(i, s[i].size()) ;
            vis[i]-- ;
        }
    }
    cout << ans << endl ;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章