【华为OD机试】-(A卷+B卷+C卷+D卷)-2024真题合集目录
题目描述
给定 M(0 < M ≤ 30)个字符(a-z),从中取出任意字符(每个字符只能用一次)拼接成长度为 N(0 < N ≤ 5)的字符串,要求相同的字符不能相邻,计算出给定的字符列表能拼接出多少种满足条件的字符串,输入非法或者无法拼接出满足条件的字符串则返回0。
输入描述
给定的字符列表和结果字符串长度,中间使用空格(" ")拼接
输出描述
满足条件的字符串个数
用例1
输入
abc 1
输出
3
说明
给定的字符为a,b,c,结果字符串长度为1,可以拼接成a,b,c,共3种
用例2
输入
dde 2
输出
2
说明
给定的字符为dde,结果字符串长度为2,可以拼接成de,ed,共2种
考点
回溯算法
解题思路
本题可以用回溯算法求解,算是同等分值里较为简单的题目,没有复杂的输入,也没有难以理解的题目描述。只需要注意一点,就是相邻的字母不能相同,只要在递归到当前字母时和前一个字母比较下是否相同,相同则continue即可。本题貌似用不到树层去重,写了也运行不到,因为在上一句有更宽松的continue条件。
代码
c++
#include <bits/stdc++.h>
using namespace std;
set<string> res;
void dfs(string str, bool *used, int lev, string ans, int m) {
if(lev==m) {
res.insert(ans);
return;
}
int n=str.size();
for(int i=0;i<n;i++) {
if(used[i]) continue;
if(i>0 && str[i]==str[i-1]) continue; //相邻字母相同的情况省略
if(i>0 && str[i]==str[i-1] && !used[i-1]) continue; //树层去重
used[i]=true;
dfs(str, used, lev+1, ans+to_string(str[i]),m);
used[i]=false;
}
}
int main() {
int m;
string str;
cin>>str>>m;
in