6Luffy6

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

[NOIP2000 提高组] 单词接龙

传送锚点:https://www.luogu.com.cn/problem/P1019

题目描述

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

输入格式

输入的第一行为一个单独的整数 n 表示单词数,以下 n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。

输出格式

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

样例 #1

样例输入 #1

5
at
touch
cheat
choose
tact
a

样例输出 #1

23

提示

样例解释:连成的“龙”为 atoucheatactactouchoose

n20

思路

code

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 25;
int n;
string words[maxn];
int g[maxn][maxn];//g[i][j]代表第i个单词与第j个单词能够接龙部分的长度
int used[maxn];//记每个单词使用次数
int res = 0;//记录接龙单词最长长度
void dfs(string dragon, int x) {//x为第几个单词
	res = max(res, (int)dragon.size());
	used[x]++;
	for (int i = 0; i < n; i++) {
		if (g[x][i] && used[i] < 2) {//第x个单词和第i单词能否接龙,每个单词最多出现2次
			dfs(dragon + words[i].substr(g[x][i]),i);
		}
	}
	used[x]--;

}
int main()
{
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> words[i];
	}
	char start;
	cin >> start;
	for (int i = 0; i < n; i++) {//对输入的单词,看是否存在接龙的部分
		for (int j = 0; j < n; j++) {
			string a = words[i];
			string b = words[j];
			for (int k = 1; k < min(a.size(), b.size()); k++) {
				if (a.substr(a.size() - k) == b.substr(0, k)) {
					g[i][j] = k;//接龙的部分,接龙后单词才越长
					break;//要实现接龙单词最长
				}
			}
		}
	}
	for (int i = 0; i < n; i++) {//找与start首字母相同的单词
		if (words[i][0] == start) {
			dfs(words[i], i);
		}
	}
	cout << res << endl;
	return 0;
}

posted on   极客三刀流  阅读(73)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示