NOI2.5 8783:单词接龙

本文详细介绍了NOI2.5中8783题‘单词接龙’的背景、规则及解题思路。通过分析如何在大规模词汇库中寻找合法的单词接续,探讨了字符串匹配、字典树和动态规划等算法在解决此类问题中的应用,并提供了高效的解决方案和实战经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述

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

输入
输入的第一行为一个单独的整数n(n<=20)表示单词数,以下n行每行有一个单词(只含有大写或小写字母,长度不超过20),输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在。
输出
只需输出以此字母开头的最长的“龙”的长度。
样例输入
5
at
touch
cheat
choose
tact
a
样例输出
23
提示

连成的“龙”为atoucheatactactouchoose


首先,字符串接龙这种东西,是非常恶心的,其次,处理接头的地方也不好做,最后,每个单词还可以访问两次,这也是个麻烦的地方。


思路:先运用深搜来作为主要核心,在单独写一个函数处理字符串,先直接加上总长度,重复的长度也加上,再输出二者的差就OK   O(∩_∩)O~


PS:

如果你一直是五分,看看你有没有考虑以下问题:

1、看看每个字符串是否起到最大作用。

2、比如“adcd”和“dcde”,最大可以组合成“adcdcde”,而不是“adcde”


AC代码如下:


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[21][21],c[20];
int k,v[21],n;
int check(int p,int q)
{
	bool eee;
	int i,j,o,pl=strlen(a[p]),ql=strlen(a[q]);
	for(i=1;i<min(pl,ql);i++)
	{
		eee=0;
		for(j=pl-i,o=0;j<pl;o++,j++)
			if(a[p][j]!=a[q][o])
				eee=1;
		if(!eee)
			return i;
	}
	return 0;
}
void find(int s,int ss,int x)
{
	int i,sss;
	for(i=0;i<n;i++)
		if(v[i]<2)
		{
			sss=check(x,i);
			if(sss)
			{
				v[i]++;
				find(s+strlen(a[i]),ss+sss,i);
				v[i]--;
			}
		}
	if(s-ss>k)
		k=s-ss;
}
int main()
{
	int i;
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%s",a[i]);
	scanf("\n%c",&c[0]);
	for(i=0;i<n;i++)
		if(a[i][0]==c[0])
		{
			v[i]=1;
			find(strlen(a[i]),1,i);
			v[i]=0;
		}
	printf("%d",k+1);
}

### C语言实现单词排序 为了实现在C语言中对单词进行排序的功能,可以采用多种方法。一种常见的方式是利用字符串处理函数以及标准库中的`qsort()`来进行快速排序。下面展示了一个完整的程序示例,该程序读取一系列由空格分隔的单词作为输入,并按照字母顺序对其进行升序排列。 ```c #include <stdio.h> #include <string.h> #define MAX_WORDS 100 /* 定义最大允许存储的单词数量 */ #define WORD_LENGTH 50 /* 单词的最大长度 */ /* 比较两个字符串并返回比较结果用于 qsort 函数 */ int compare(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } int main() { char words[MAX_WORDS][WORD_LENGTH]; // 存储多个固定大小的字符数组表示各个单词 char input[1024]; int count = 0; printf("请输入若干个以空格分开的英文单词:\n"); fgets(input, sizeof(input), stdin); // 使用 strtok 解析输入串得到单个单词存入二维数组 char *token; token = strtok(input, " \n"); while (token != NULL && count < MAX_WORDS) { strcpy(words[count], token); ++count; token = strtok(NULL, " \n"); } if (count > 0) { // 对解析出来的所有单词调用 qsort 进行排序 qsort((void *)words, count, sizeof(char *), compare); // 输出已排序后的单词序列 printf("按字典顺序排序后的单词如下所示:\n"); for (int i = 0; i < count; ++i) { printf("%s ", words[i]); } putchar('\n'); } else { puts("未检测到任何有效的单词!"); } return 0; } ``` 此代码片段展示了如何接收用户输入的一组单词并通过内置的`qsort()`算法完成排序操作[^1]。需要注意的是,在实际应用环境中可能还需要考虑更多边界情况,比如更长的单词链表、不同的编码方式支持等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值