您的位置:首页 > 游戏 > 游戏 > 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的字符串拼接游戏(200分) - 三语言AC题解(Python/Java/Cpp)

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的字符串拼接游戏(200分) - 三语言AC题解(Python/Java/Cpp)

2024/9/24 21:27:35 来源:https://blog.csdn.net/Qmtdearu/article/details/140020800  浏览:    关键词:【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的字符串拼接游戏(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员

✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解

💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导

👏 感谢大家的订阅➕ 和 喜欢💗

📎在线评测链接

https://app5938.acapp.acwing.com.cn/contest/2/problem/OD1088

🌍 评测功能需要 ⇒ 订阅专栏 ⇐ 后私信联系清隆解锁~

🍓OJ题目截图

在这里插入图片描述

文章目录

    • 📎在线评测链接
    • 🍓OJ题目截图
    • 🌲 LYA的字符串拼接游戏
      • 问题描述
      • 输入格式
      • 输出格式
      • 样例输入
      • 样例输出
      • 样例解释
      • 样例输入
      • 样例输出
      • 样例解释
      • 数据范围
      • 题解
      • 参考代码

🌲 LYA的字符串拼接游戏

问题描述

LYA最近迷上了一款字符串拼接游戏。游戏规则如下:

给定一个由小写字母组成的字符集合,以及一个正整数 N N N。从字符集合中任意取出字符(每个字符只能用一次),拼接成一个长度为 N N N 的字符串,要求相邻的字符不能相同。

请帮助LYA计算出,给定的字符集合能拼接出多少种满足条件的字符串。如果输入非法或无法拼接出满足条件的字符串,则输出 0 0 0

输入格式

输入为一行,包含一个由小写字母组成的字符串和一个正整数 N N N,两者之间用一个空格分隔。

  • $1 \le $ 字符串长度 ≤ 29 \le 29 29
  • 1 ≤ N ≤ 5 1 \le N \le 5 1N5

输出格式

输出一个整数,表示能拼接出的满足条件的字符串个数。

样例输入

abc 1

样例输出

3

样例解释

给定的字符集合为 abc,结果字符串长度为 1 1 1,可以拼接出 abc 三种字符串,因此输出 3 3 3

样例输入

dde 2

样例输出

2

样例解释

给定的字符集合为 dde,结果字符串长度为 2 2 2,可以拼接出 deed 两种字符串,因此输出 2 2 2

数据范围

  • $1 \le $ 字符串长度 ≤ 29 \le 29 29
  • 1 ≤ N ≤ 5 1 \le N \le 5 1N5

题解

本题可以用回溯法(DFS)来解决。

我们定义一个布尔数组 vis 来记录每个字符是否被使用过。然后从字符集合的第一个字符开始,尝试将它加入结果字符串。如果当前字符没有被使用过,且与结果字符串的最后一个字符不同,就将它加入结果字符串,并标记为已使用。

接下来,我们继续尝试从剩余的未使用字符中选择下一个字符,直到结果字符串的长度达到 N N N。如果能够成功构造出一个满足条件的字符串,就将答案加一。

在尝试每一步时,我们都需要跳过重复的字符,以避免重复计算。这可以通过对字符集合进行排序,然后在遍历时跳过连续相同的字符来实现。

时间复杂度为 O ( N ! × M ) O(N! \times M) O(N!×M),其中 N N N 为结果字符串的长度, M M M 为字符集合的长度。空间复杂度为 O ( M ) O(M) O(M),用于存储字符集合和访问数组。

参考代码

  • Python
from itertools import permutationsdef count_strings(chars, n):res = 0for perm in permutations(chars, n):if all(perm[i] != perm[i+1] for i in range(n-1)):res += 1return reschars, n = input().split()
n = int(n)
print(count_strings(chars, n))
  • Java
import java.util.*;public class Main {static int k;static char[] cs;static int res;static boolean[] vis;static StringBuilder sb = new StringBuilder();static int n;public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s = sc.next();n = s.length();k = sc.nextInt();cs = s.toCharArray();vis = new boolean[n];Arrays.sort(cs);dfs(0);System.out.println(res);}static void dfs(int u) {if (u == k) {res++;return;}for (int i = 0; i < n; i++) {if (vis[i]) {continue;}if (i > 0 && cs[i] == cs[i - 1] && !vis[i - 1]) {continue;}if (sb.length() > 0 && sb.charAt(sb.length() - 1) == cs[i]) {continue;}vis[i] = true;sb.append(cs[i]);dfs(u + 1);sb.deleteCharAt(sb.length() - 1);vis[i] = false;}}
}
  • Cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int n, k;
string cs;
int res = 0;
vector<bool> vis;
string sb;void dfs(int u) {if (u == k) {res++;return;}for (int i = 0; i < n; i++) {if (vis[i]) {continue;}if (i > 0 && cs[i] == cs[i - 1] && !vis[i - 1]) {continue;}if (!sb.empty() && sb.back() == cs[i]) {continue;}vis[i] = true;sb.push_back(cs[i]);dfs(u + 1);sb.pop_back();vis[i] = false;}
}int main() {cin >> cs >> k;n = cs.length();vis.resize(n, false);sort(cs.begin(), cs.end());dfs(0);cout << res << endl;return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com