华为机考真题 -- 字符串拼接

题目描述:

给定 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 种

C++源码:

#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
using namespace std;

int countValidStrings(const string& chars, int N) {
    if (N > chars.size()) return 0;
    vector<vector<int>> dp(N + 1, vector<int>(chars.size() + 1, 0));
    unordered_set<char> uniqueChars(chars.begin(), chars.end());

    // 初始化
    for (int i = 0; i <= chars.size(); ++i) {
        dp[1][i] = uniqueChars.size();
    }

    // 动态规划
    for (int len = 2; len <= N; ++len) {
        for (int used = 1; used <= chars.size(); ++used) {
            // 不使用第 used 个字符的情况
            dp[len][used] = dp[len][used - 1];
            // 使用第 used 个字符的情况,需要保证前一个字符不是当前字符
            if (used >= 2 && chars[used - 2] != chars[used - 1]) {
                dp[len][used] += dp[len - 1][used - 2];
            }
        }
    }

    return dp[N][chars.size()];
}

int main() {
    string input;
    getline(cin, input);
    if (input.find(' ') == string::npos) {
        cout << 0 << endl;
        system("pause");
        return 0;
    }
    string chars = input.substr(0, input.find(' '));
    int N = stoi(input.substr(input.find(' ') + 1));

    if (N <= 0 || N > 5 || chars.size() > 30) {
        cout << 0 << endl;
    }
    else {
        cout << countValidStrings(chars, N) << endl;
    }

    system("pause");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值