C++-单词接龙 解题教程

【Horn Studio】编程专栏: 单词接龙 解题思路

题目

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如beast和astonish,如果接成一条龙则变为beastonish,另外相邻的两部分不能存在包含关系,例如at和atide间不能相连。

输入

输入的第一行为一个单独的整数n(1<=n<=12)表示单词数,以下n行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

输出

只需输出以此字母开头的最长的“龙”的长度。

样例输入 复制

5
at
touch
cheat
choose
tact
a

样例输出 复制

23

提示

连成的“龙”为atoucheatactactouchoose

来源

思路

对于这道题,有一个很好用的函数:substr——产生子串

返回一个新建的 初始化为string对象的子串的拷贝string对象。

子串是,在字符位置pos开始,跨越len个字符(或直到字符串的结尾,以先到者为准)对象的部分。

特别感谢 繁小华 提供了注解,原文链接:https://blog.csdn.net/sunshihua12829/article/details/50484966

拥有了这个,就是解决这道接龙题目的关键!

e.g:

4 3 2 1         4 3

2 1 5 6       4 3 2 1  ×   因为它包含了所有上一个字串

因此,最大截取限度为(n-1)

这道看似二级的题目,实则却拥有四级的dfs,笑里藏刀请注意!

代码

#include <bits/stdc++.h>

using namespace std;

int n,anslen = 0;
string s[20];
int vis[1000000],k[20][20];

int csh(string x,string y){
    int l1 = x.length(),l2 = y.length();
    for (int i = 1;i <= min(l1,l2) - 1;i++){
        if(x.substr(l1 - i,i) == y.substr(0,i)){
            return i;
        }
    }
    return 0;
}

void dfs(int x,int len){
    anslen = max(len,anslen);
    for (int i = 1;i <= n;i++){
        if(vis[i] == 2 || k[x][i] == 0){
            continue;
        }
        vis[i]++;
        dfs(i,len + s[i].length() - k[x][i]);
        vis[i]--; 
    }
}

int main(){
    scanf("%d",&n);
    for (int i = 1;i <= n+1;i++)
        cin>>s[i];
    for (int i = 1;i <= n+1;i++){
        for (int j = 1;j <= n+1;j++){
            k[i][j] = csh(s[i],s[j]);
        }
    } 
        
    for (int i = 1;i <=n;i++){
        if(s[n+1][0] != s[i][0]){
            continue;
        }
        vis[i]++;
        dfs(i,s[i].length());
        vis[i]--;
    }
    
    printf("%d",anslen);
    return 0;
}

 

 

彩蛋

:欸,我就不给dfs代码~

 

posted @ 2022-03-20 09:32  冯子坤  阅读(447)  评论(2编辑  收藏  举报