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;
}

 

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