当前位置: 首页 > news >正文

华为OD机试真题 - 抢7游戏(Python/JS/C/C++ 2024 D卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

A、B两个人玩抢7游戏,游戏规则为A先报一个起始数字X (10 <= X <= 10000),B报下一个数字Y,(0<X-Y<3),A再报一个数字Z(0<Y-Z<3),以此类推,直到其中一个抢到7,抢到7即为胜者,在B赢得比赛的情况下,一共有多少种组合?

二、输入描述

起始数字M,如100

10 <= M <= 10000

三、输出描述

B能赢得比赛的组合次数。

四、解题思路

  1. 问题分析:
    • 这个游戏本质上是从起始数字 m 到 7 的一个递减过程。
    • 每次可以选择减1或减2,对应了两种操作。
    • B 想要赢,必须在轮到自己时拿到 7。
  2. 问题转化:
    • 我们可以将问题转化为排列组合问题。
    • 从 m 到 7 的过程可以看作是排列若干个"减1"和"减2"操作。
    • "减1"操作的次数 = m - 7
    • 总操作次数必须为奇数,这样最后一步(到7)才会是 B 操作。
  3. 计算策略:
    • 初始时,所有操作都是"减1",即 oneCount = m - 7, twoCount = 0。
    • 然后我们逐步将两个"减1"合并为一个"减2",遍历所有可能的组合。
    • 对于每种有效组合(总步数为奇数),计算其不重复排列数。
  4. 排列数计算:
    • 使用组合数学公式:(oneCount + twoCount)! / (oneCount! * twoCount!)
    • 这个公式计算了在总操作序列中,"减1"和"减2"的所有不重复排列方式。
  5. 大数处理:
    • 由于数字可能很大,我们使用 BigInteger 来处理计算,避免溢出。
    • 预先计算阶乘,存储在数组中,以提高效率。
  6. 结果累加:
    • 对每种有效组合的排列数进行累加,得到最终 B 获胜的总情况数。

五、测试用例

1、输入

10

2、输出

1

3、说明

只有一种赢的组合,A起始选择10,B接着选择9,A接着选择8,B接着选择7赢得胜利。

六、Python算法源码

from math import factorial
from functools import lru_cache

@lru_cache(None)
def get_permutation_count(one_count, two_count):
    if one_count == 0 or two_count == 0:
        return 1
    else:
        total_steps = one_count + two_count
        return factorial(total_steps) // (factorial(one_count) * factorial(two_count))

def main():
    m = int(input("请输入起始数字: "))  # 读取起始数字

    one_count = m - 7  # 初始的1的数量(每次减1的操作数)
    two_count = 0      # 初始的2的数量(每次减2的操作数)
    ans = 0  # 用于记录B赢的情况总数

    # 遍历所有可能的1和2的组合
    while one_count >= 0:
        # 当总步数为奇数时,B才能赢(因为A先手)
        if (one_count + two_count) % 2 != 0:
            # 计算当前组合的排列数,并加到总数中
            ans += get_permutation_count(one_count, two_count)
        # 将两个1合并为一个2(即减少两次"减1",增加一次"减2")
        one_count -= 2
        two_count += 1

    # 输出结果
    print(ans)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

function factorial(n) {
    if (n === 0) return 1;
    let result = 1;
    for (let i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

function getPermutationCount(oneCount, twoCount) {
    if (oneCount === 0 || twoCount === 0) {
        return 1;
    } else {
        let totalSteps = oneCount + twoCount;
        return factorial(totalSteps) / (factorial(oneCount) * factorial(twoCount));
    }
}

function main() {
    const m = parseInt(prompt("请输入起始数字: "), 10);  // 读取起始数字

    let oneCount = m - 7;  // 初始的1的数量(每次减1的操作数)
    let twoCount = 0;      // 初始的2的数量(每次减2的操作数)
    let ans = 0;  // 用于记录B赢的情况总数

    // 遍历所有可能的1和2的组合
    while (oneCount >= 0) {
        // 当总步数为奇数时,B才能赢(因为A先手)
        if ((oneCount + twoCount) % 2 !== 0) {
            // 计算当前组合的排列数,并加到总数中
            ans += getPermutationCount(oneCount, twoCount);
        }
        // 将两个1合并为一个2(即减少两次"减1",增加一次"减2")
        oneCount -= 2;
        twoCount += 1;
    }

    // 输出结果
    console.log(ans);
}

main();

八、C算法源码

#include <stdio.h>

typedef unsigned long long ull;

// 计算阶乘
ull factorial(int n) {
    if (n == 0) return 1;
    ull result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

// 计算不重复的全排列数
ull get_permutation_count(int one_count, int two_count) {
    if (one_count == 0 || two_count == 0) {
        return 1;
    } else {
        int total_steps = one_count + two_count;
        return factorial(total_steps) / (factorial(one_count) * factorial(two_count));
    }
}

int main() {
    int m;
    printf("请输入起始数字: ");
    scanf("%d", &m);  // 读取起始数字

    int one_count = m - 7;  // 初始的1的数量(每次减1的操作数)
    int two_count = 0;      // 初始的2的数量(每次减2的操作数)
    ull ans = 0;  // 用于记录B赢的情况总数

    // 遍历所有可能的1和2的组合
    while (one_count >= 0) {
        // 当总步数为奇数时,B才能赢(因为A先手)
        if ((one_count + two_count) % 2 != 0) {
            // 计算当前组合的排列数,并加到总数中
            ans += get_permutation_count(one_count, two_count);
        }
        // 将两个1合并为一个2(即减少两次"减1",增加一次"减2")
        one_count -= 2;
        two_count += 1;
    }

    // 输出结果
    printf("%llu\n", ans);

    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <boost/multiprecision/cpp_int.hpp>  // 使用Boost库中的大整数类型

using namespace std;
using namespace boost::multiprecision;

vector<cpp_int> factor;

// 初始化阶乘数组
void initFactor(int n) {
    factor.resize(n + 1);
    factor[0] = 1;  // 0! = 1
    for (int i = 1; i <= n; i++) {
        factor[i] = factor[i - 1] * i;
    }
}

// 计算不重复的全排列数
cpp_int getPermutationCount(int oneCount, int twoCount) {
    if (oneCount == 0 || twoCount == 0) {
        return 1;  // 只有1或只有2的情况,只有一种排列方式
    } else {
        // 使用组合数学公式计算不重复的排列数
        // 公式:(oneCount + twoCount)! / (oneCount! * twoCount!)
        return factor[oneCount + twoCount] / (factor[oneCount] * factor[twoCount]);
    }
}

int main() {
    int m;
    cout << "请输入起始数字: ";
    cin >> m;  // 读取起始数字

    // 初始化阶乘数组,最大需要计算 (m-7)!
    initFactor(m - 7);

    int oneCount = m - 7;  // 初始的1的数量(每次减1的操作数)
    int twoCount = 0;      // 初始的2的数量(每次减2的操作数)
    cpp_int ans = 0;       // 用于记录B赢的情况总数

    // 遍历所有可能的1和2的组合
    while (oneCount >= 0) {
        // 当总步数为奇数时,B才能赢(因为A先手)
        if ((oneCount + twoCount) % 2 != 0) {
            // 计算当前组合的排列数,并加到总数中
            ans += getPermutationCount(oneCount, twoCount);
        }
        // 将两个1合并为一个2(即减少两次"减1",增加一次"减2")
        oneCount -= 2;
        twoCount += 1;
    }

    // 输出结果
    cout << ans << endl;

    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

相关文章:

  • 间隙锁对数据库并发性能的影响
  • 扑捉一只耿鬼(HTML文件)
  • blender云渲染来了,blender云渲染教程!
  • Java面试题总结-基础和框架-面试题一
  • 微课录制技巧|高效录制微课的方法,如何高效录制微课?
  • 数据库设计中的需求分析
  • 第三届人工智能与智能信息处理国际学术会议(AIIIP 2024)
  • 大模型之三十-语音合成TTS(coqui)
  • 学习node.js十三,文件的上传于下载
  • Spring框架的核心模块有哪些
  • Python 调用手机摄像头
  • JavaScript(进阶篇)
  • 《浔川社团一周总结(第一周)》——浔川社团官方
  • sqlmap简介及安装
  • 数仓工具—Hive语法之URL 函数
  • Redis进阶(七):分布式锁
  • 微信小程序路由跳转之间的区别
  • Java语言程序设计基础篇_编程练习题**17.20 (二进制编辑器)
  • 第三章 Mybatis 常用工具
  • MacBook真的不能打游戏吗?Mac打游戏会损坏电脑吗?苹果电脑怎么玩游戏
  • 董军在第六届联合国维和部长级会议上作大会发言
  • 王征、解宁元、牛恺任西安市副市长
  • 4台肺癌手术,2名“90后”患者,这届年轻人的肺怎么了?
  • 中国-拉共体成员国重点领域合作共同行动计划(2025-2027)
  • 上海北外滩,未来五年将如何“长个子”“壮筋骨”?
  • 排污染黑海水后用沙土覆盖黑泥?汕尾环保部门:非欲盖弥彰