NOIP2000提高组T3:单词接龙

题目描述

单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母(不是单词),请你计算以这个字母开头的长度最长的“龙”,每个单词最多在“龙”中出现两次。

要注意的是,两个单词接龙规则如下:

  1. 如果第一个单词的后面的连续若干字母与第二个单词前面的连续若干字母依次相同,则这两个单词可以接龙,例如 beast 和 astonish ,如果接成一条龙则变为 beastonish。
  2. 两个单词接成一条龙后,龙的长度要比两个单词的长度都长。例如单词 at 和 atide 接成一条龙后为atide,龙的长度与第二个单词相同,所以这两个单词不能接龙。而单词ababab和ababab,可以接成ababababab,但不能为ababab。
  3. 接龙时,如果两个单词接龙后的单词有多种情况,要尽可能保证接龙后龙的长度最长。例如cabab和ababc,一定要接成cabababc,为而不是cababc

输入格式
输入的第一行为一个单独的整数 n 表示单词数,以下 n 行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。

你可以假定以此字母开头的“龙”一定存在。

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

数据范围
n ≤ 20 n≤20 n20

输入样例:

5
at
touch
cheat
choose
tact
a

输出样例:

23

提示
连成的“龙”为 atoucheatactactouchoose。

算法思想 DFS

从数据范围 n < = 20 n<=20 n<=20可以考虑使用DFS算法,尝试所有以“龙”字母开头的单词进行接龙,在搜索中计算最长的“龙”的长度。

注意:

  1. 为了能快速判断出两个单词是否能够“接龙” ,可以预先将所有单词之间的关系g[i][j]g[i][j] = 3表示第i个单词和第j个单词可以接龙,且相同部分的长度为3
  2. 为了保证每个单词最多在“龙”中出现两次,可以使用used[i]记录单词使用次数,例如:used[i] = 2表示第i个单词使用了两次。

代码实现

#include <iostream>
using namespace std;
const int N = 25;
int n, ans;
string word[N];
//g[i][j]表示单词i和单词j是否可以相连
//如果可以,重合部分的最小长度是多少
int g[N][N];
//used[i]表示单词i的使用次数
int used[N];

//dragon当前龙,上次使用的单词编号
void dfs(string dragon, int last)
{
    ans = max(ans, (int)dragon.size());

    //单词last使用次数增加1次
    used[last] ++;

    for(int i = 0; i < n; i ++)
    {
        //单词i使用不足两次,并且单词last和i能够连接
        if(used[i] < 2 && g[last][i])
            //新龙为dragon + word[i].substr(g[last][i]),使用的是单词i
            dfs(dragon + word[i].substr(g[last][i]), i);
    }

    used[last] --; //回溯
}

int main()
{
    cin >> n;

    for(int i = 0; i < n; i++) cin >> word[i];

    char st;
    cin >> st;

    //处理所有单词是否可以相连
    //如果可以,则重合部分的最小长度是多少
    for(int i = 0; i < n; i++)
        for(int j = 0; j < n; j++)
        {
            string a = word[i], b = word[j];
            //枚举所有长度,注意这里要严格小于两个串中最小的长度
            for(int k = 1; k < min(a.size(), b.size()); k++)
            {
               //如果a的后缀和b的前缀相等 
               if(a.substr(a.size() - k, k) == b.substr(0, k))
               {
                   g[i][j] = k;
                   //可以任意选择重合部分的长度,但其长度必须大于等于1,
                   //注意,这里找到后中断,保证重叠的部分最小
                   break;
               }
            }
        }

    for(int i = 0; i < n; i++)
    {
        if(word[i][0] == st)
            dfs(word[i], i);
    }

    cout << ans << endl;

    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这是关于单词接龙题,类似于我们平常玩的成语接龙。现在我们已经知道了一单词,并给定了一个开头的字母,要求找到一个最长的以这个字母开头的“龙”,每次添加一个新的单词时,要求与前一个单词有相似之处,比如可以有共同的前缀或后缀。但是有些单词不能连续出现,如题目中给出的例子“beast”和“astonish”,如果接成“beastonish”就不行了。还有一些单词之间没有相似之处,不能相连,比如“at”和“atide”。 ### 回答2: 单词接龙是一款非常受大家欢迎的游戏,它需要玩家根据给定的首字母,从已知单词中拼出最长的“龙”。在游戏中,每个单词最多只能出现两次,且相邻单词的重合部分合并为一部分。同时,相邻单词的两部分不能存在包含关系。 要想拼出最长的“龙”,我们需要灵活运用词汇书和词根词缀的知识。首先,我们需要了解每个单词的意思和拼写,以便在拼接过程中不出现错误。其次,我们需要了解英语中常见的词根词缀,例如“un-”、“re-”、“dis-”等,这可以给我们提供更多的合选择。 当然,为了在游戏中获胜,我们还需要注意以下几个技巧: 1. 固定“龙”的末尾单词游戏开始时,我们可以先选择一些比较长的单词作为“龙”的末尾单词,这样可以尽可能扩大拼接的空间。当然,要保证这些单词的首字母与游戏给定的首字母相同。 2. 利用转换词 转换词是指在词根、词缀和单词拼写上进行微小变化,以扩大单词合的可能性。例如,可以将“beauty”转换为“beautify”、将“artist”转换为“artistic”等。 3. 选择诗句中的单词 在英语诗歌中,有些单词经常出现,例如“love”、“dream”、“heart”等,我们可以利用这些单词增加拼接的可能性。 4. 利用同音词、近义词 在英语中,有些单词在发音或意思上非常相似,例如“fair”和“fare”、“fly”和“fry”等,我们可以利用这些单词扩大合的可能性。 综上所述,要想在单词接龙中获胜,我们需要灵活运用词汇书和词根词缀的知识,同时注意一些技巧,例如固定“龙”的末尾单词、利用转换词、选择诗句中的单词等。在不断尝试和探索中,相信我们一定可以拼出最长的“龙”。 ### 回答3: 单词接龙是一款经典的文字游戏,主要是通过拼接单词来构建一个以某个字母开头的最长单词链。这个游戏不仅能够锻炼我们的词汇量和语言能力,还能提高我们的思维能力和创造力。 在这个游戏中,最重要的一点就是要有足够的单词库,因为只有当我们有足够的单词可选时,才能构建出一个更长的单词链。当然,还需要注意每个单词只能在链中出现不超过两次,这样才能体现游戏的难度和趣味性。 在构建单词链时,还需要注意每两个相邻单词的连接方式。不同的单词链可能会有不同的策略,但总的原则是在选择单词时要尽量避免相邻单词之间出现包含的情况,也就是要选择尽可能不相似的单词,这样才能形成一个更有趣、更富挑战性的单词链。 总的来说,单词接龙是一款好玩的游戏,可以让我们在娱乐中学习,让我们在挑战中成长。但需要注意的是,我们应该保持良好的游戏态度,尊重游戏规则,在比赛中互相帮助,共同享受游戏乐趣。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少儿编程乔老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值