华为OD机试 2024E卷题库疯狂收录中,刷题点这里
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
斗地主起源于湖北十堰房县,据说是一位叫吴修全的年轻人根据当地流行的扑克玩法”跑得快”改编的,如今已风靡整个中国,并流行于互联网上。
牌型:单顺,又称顺子,最少5张牌,最多12张牌(3…A)不能有2,也不能有大小王,不计花色。
例:3-4-5-6-7-8,7-8-9-10-J-Q,3-4-5-6-7-8-9-10-J-Q-K-A可用的牌3<4<5<6<7<8<9<10 1、输入 2、输出 对手可能构成的最长的顺子(如果有相同长度的顺子,输出牌面最大的那一个) 如果无法构成顺子,则输出NO-CHAIN 输入的第一行为当前手中的牌 输入的第二行为已经出过的牌 最长的顺子 3-3-4-4-5-A-5-6-2-8-3-9-10-Q-7-K-J-10-B 9-10-J-Q-K-A 下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分) 本文收录于,华为OD机试真题(Python/JS/C/C++) 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
二、输入描述
三、输出描述
输入
输出
说明
3-3-3-3-4-4-5-5-6-7-8-9-10-J-Q-K-A
A-4-5-6-7-8-8-89-10-J-Q-K-A
四、解题思路
五、测试用例
1、输入
A-4-5-8-8-10-C-6-7-82、输出
3、说明
六、Python算法源码
def main():
# 获取输入:当前手中的牌 + 已经出过的牌,并合并
my_pokers = input().strip()
already_pokers = input().strip()
merge_pokers = my_pokers + "-" + already_pokers
merge_pokers = merge_pokers.split("-")
# 为方便后续判断顺子,将JQKA转为int,reverse_map供后续打印顺子使用
char2int = {'J': 11, 'Q': 12, 'K': 13, 'A': 14}
reverse_map = {v: k for k, v in char2int.items()}
# 定义数组表示对手的牌,遍历前面合并牌数组(当前手中的牌 + 已经出过的牌),每遍历到一张牌,对手的牌对应的数组元素 - 1
# 注意: 数组长度由来:顺子有效的牌为3-14,所以长度为14 - 3 + 1
# 注意:为什么-3:有效的顺子牌从3开始,而数组下标需要从0开始
their_pokers = [0] * (14 - 3 + 1)
for poker in merge_pokers:
if len(poker) > 1: # 10
their_pokers[int(poker) - 3] -= 1
elif poker in char2int: # JQKA
their_pokers[char2int[poker] - 3] -= 1
elif poker not in ['2', 'B', 'C']:
their_pokers[int(poker) - 3] -= 1
# 动态规划获取最长的顺子,当前牌的顺子长度只与前一个牌的顺子长度和当前牌是否可用有关
prev = 1 if their_pokers[0] > -4 else 0
max_len = float('-inf')
current = 0
start = 1
for i in range(1, len(their_pokers)):
if their_pokers[i] > -4: # 有剩余牌时,拼接顺子
current = prev + 1
if current > max_len:
max_len = current
start = i + 3 - max_len + 1 # 注意这里+3,是由于数组下标和扑克牌之间差了3
else: # 无剩余牌,顺子长度置为0
current = 0
prev = current
# 符合条件
if max_len >= 5:
straight = "-".join(str(reverse_map.get(poker, poker)) for poker in range(start, start + max_len))
print(straight)
else:
print("NO-CHAIN")
if __name__ == "__main__":
main()
七、JavaScript算法源码
function main() {
const readline = require('readline-sync');
// 获取输入:当前手中的牌 + 已经出过的牌,并合并
let myPokers = readline.question().trim();
let alreadyPokers = readline.question().trim();
let mergePokers = myPokers + "-" + alreadyPokers;
mergePokers = mergePokers.split("-");
// 为方便后续判断顺子,将JQKA转为int, reverseMap供后续打印顺子使用
const char2int = { 'J': 11, 'Q': 12, 'K': 13, 'A': 14 };
const reverseMap = Object.fromEntries(Object.entries(char2int).map(([k, v]) => [v, k]));
// 定义数组表示对手的牌
const theirPokers = new Array(14 - 3 + 1).fill(0);
mergePokers.forEach(poker => {
if (poker.length > 1) { // 10
theirPokers[parseInt(poker) - 3]--;
} else if (char2int.hasOwnProperty(poker)) { //JQKA
theirPokers[char2int[poker] - 3]--;
} else if (poker !== '2' && poker !== 'B' && poker !== 'C') {
theirPokers[parseInt(poker) - 3]--;
}
});
// 动态规划获取最长的顺子,当前牌的顺子长度只与前一个牌的顺子长度和当前牌是否可用有关
let prev = theirPokers[0] > -4 ? 1 : 0;
let current = 0;
let max = -Infinity;
let start = 1;
for (let i = 1; i < theirPokers.length; i++) {
if (theirPokers[i] > -4) {
current = prev + 1;
if (current > max) {
max = current;
start = i + 3 - max + 1; // 注意这里+3,是由于数组下标和扑克牌之间差了3
}
} else {
current = 0;
}
prev = current;
}
// 符合条件
if (max >= 5) {
const straight = Array.from({ length: max }, (_, i) => {
const poker = start + i;
return poker > 10 ? reverseMap[poker] : poker;
}).join('-');
console.log(straight);
} else {
console.log("NO-CHAIN");
}
}
// 执行主函数
main();
八、C算法源码
#include
九、C++算法源码
#include