AcWing 1117. 单词接龙
. 单词接龙
一、题目描述
单词接龙是一个与我们经常玩的成语接龙相类似的游戏。
现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”,每个单词最多被使用两次。
在两个单词相连时,其重合部分合为一部分,例如 和 ,如果接成一条龙则变为 。
我们 可以任意选择重合部分的长度,但其长度必须大于等于,且 严格小于两个串的长度 ,例如 和 间不能相连。
输入格式
输入的第一行为一个单独的整数 表示单词数,以下 行每行有一个单词(只含有大写或小写字母,长度不超过),输入的最后一行为一个单个字符,表示 龙 开头的字母。
你可以假定以此字母开头的 龙 一定存在。
输出格式
只需输出以此字母开头的最长的 龙 的长度。
数据范围
,单词随机生成。
输入样例:
5
at
touch
cheat
choose
tact
a
输出样例:
23
提示
连成的 龙 为 atoucheatactactouchoose
。
二、解题思路
- 遍历所有单词,找出 开头字母 是 给定开始字母 的单词,它们都有可能是第一个单词
- 假设选择的第一个单词是,那么需要逐个考查所有单词(也包括自己),是不是可以拼接在当前单词的后面,也就是 开头 与 结尾 存在 相同的子串。如果存在不同长度的子串,比如与,那么我们需要选择最短的子串,因为这样才能保证最后拼接的长度最长(贪心)
- 我们需要记录 每个单词 的 出现次数,因为题目要求最多不能超过两次
#include <bits/stdc++.h>
using namespace std;
const int N = 30;
int n;
string word[N];
int cnt[N];
int res;
int getSameLength(string a, string b) {
for (int i = 1; i < min(a.size(), b.size()); i++)
if (a.substr(a.size() - i, i) == b.substr(0, i))
return i;
return 0;
}
void dfs(int u, string str) {
res = max((int)str.size(), res); // 不断刷新龙的长度
// 记录该字符串使用次数
for (int i = 0; i < n; i++) { // 遍历所有字符串,找出可以接在u后面串
int len = getSameLength(word[u], word[i]);
// 最小公共长度(可以保证龙最长),并且,使用次数小于2次
// 最小公共长度对于后面的串而言,也是前缀位置
if (len && cnt[i] < 2) {
cnt[i]++;
dfs(i, str + word[i].substr(len));
cnt[i]--;
}
}
}
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++) // 枚举每个字符串
// 如果该字符串的首字母是指定的起点字母st
if (word[i][0] == st) {
cnt[i]++;
dfs(i, word[i]); // 开始将当前搜索到的字符串作为首串开始深搜
cnt[i]--;
}
cout << res << endl; // 最大长度
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-03-07 黄海的项目研发任务与定位
2020-03-07 研发过程中需要进行的测试
2020-03-07 运维工具选型
2020-03-07 防止SQL注入和XSS注入的方法总结
2018-03-07 树莓派播放天气
2018-03-07 树莓派新手入门教程
2012-03-07 CentOS下单网卡配置双IP的解决办法