(C语言)华为OD机考:统一考试 C卷 + D卷 + B卷 +A卷
目前在考C卷,经过两个月的收集整理,C卷真题已整理完毕
抽到原题的概率为2/3到3/3,也就是最少抽到两道原题。请注意:大家刷完C卷真题,最好要把B卷的真题刷一下,因为C卷的部分真题来自B卷。
真题目录:【C语言题解版】华为 OD 机试 C卷抽中题库清单(全真题库)含考点说明
专栏:(C语言)最新华为OD机试C卷+D卷+AB卷
题目描述:构成指定长度字符串的个数 (本题分值100)
给定 M(0 < M ≤ 30)个字符(a-z),从中取出任意字符(每个字符只能用一次)拼接成长度为 N(0 < N ≤ 5)的字符串,
要求相同的字符不能相邻,计算出给定的字符列表能拼接出多少种满足条件的字符串,
输入非法或者无法拼接出满足条件的字符串则返回0。
输入描述
给定的字符列表和结果字符串长度,中间使用空格(" ")拼接
输出描述
满足条件的字符串个数
用例1
输入
aab 2
输出
2
说明
只能构成ab,ba。
用例2
输入
abc 2
输出
6
说明
可以构成:ab ac ba bc ca cb 。
解题思路
使用递归和回溯的思想来生成不同的字符串。具体的逻辑如下:
-
首先,我们定义一个函数
generateDistinctStrings
,这个函数接收以下参数:可用字符集s
,目标字符串长度length
,当前已生成的字符串current
,已生成的结果集result
,以及一个标记数组used
,用来记录每个字符是否已被使用。 -
在
generateDistinctStrings
函数中,首先检查当前已生成的字符串current
的长度是否等于目标长度length
。如果等于,说明我们已经生成了一个满足长度要求的字符串,将其添加到结果集result
中,然后返回。 -
如果当前字符串
current
的长度还未达到目标长度length
,我们就需要继续添加字符。此时,我们遍历可用字符集s
中的每一个字符。对于每一个字符,我们首先检查它是否已经被使用(通过查看used
数组),以及它是否与current
的最后一个字符相同。如果字符已经被使用,或者与current
的最后一个字符相同,我们就跳过这个字符,继续检查下一个字符。 -
如果一个字符未被使用,且与
current
的最后一个字符不同,我们就将它添加到current
的末尾,然后标记这个字符为已使用,接着递归调用generateDistinctStrings
函数,以生成下一个字符。 -
在递归调用返回后,我们需要取消对当前字符的使用标记,以便在后续的遍历中可以再次使用这个字符。这就是回溯的思想,即撤销之前的选择,尝试其他的选择。
以下是对应的中文伪代码:
函数 generateDistinctStrings(s, length, current, result, used)
如果 current的长度 等于 length
将 current 添加到 result
返回
对于 s中的每一个字符 c
如果 c已被使用 或者 c与current的最后一个字符相同
继续下一次循环
标记 c为已使用
generateDistinctStrings(s, length, current + c, result, used)
取消标记 c的使用状态
C语言
#