第九届蓝桥杯省赛B组:乘积最大 C/C++解法

博客介绍了如何使用动态规划和递归法解决蓝桥杯竞赛中的一道题目,目标是找出给定整数数组中K个数的最大乘积,并考虑了数值可能为负的情况。解题思路包括计算前i项的最大值和乘积,然后通过比较选择较大的乘积进行递归计算,最终结果需对1000000009取模。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蓝桥杯:乘积最大  C/C++解法

题目描述

给定N个整数A1, A2, … AN。请你从中选出K个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数。
注意,如果X<0, 我们定义X除以1000000009的余数是负(-X)除以1000000009的余数。
即:0-((0-x) %1000000009)


【输入格式】
第一行包含两个整数N和K。
以下N行每行一个整数Ai。

对于40%的数据,1 <= K <= N <= 100
对于60%的数据,1 <= K <= 1000
对于100%的数据,1 <= K <= N <= 100000 , -100000 <= Ai <= 100000

【输出格式】
一个整数,表示答案。


【输入样例1】

5 3
-100000
-10000
2
100000
10000

【输出样例1】

999100009

【输入样例2】

5 3
-100000
-100000
-2
-100000
-100000

【输出样例2】

-999999829

解题思路

这道题可以用DP去解决。首先,求出前 i 项中最大值以及前 i 项乘积,这样的好处是在之后的递归中可以节省时间。之后调用dp_func()函数进行乘积计算。

dp_func()函数原理:
从 n 项中选出 k 个数的最大乘积等同于
            1>从 n-1 项中选出 k 个数的最大乘积
        或 2>从 n-1 项中选出 k-1 个数的最大乘积再乘以第 n 个数
之后 1> 和 2> 比较大小,选择乘积大的作为答案        (以此类推用递归法写)

注意事项: 数字乘积比较大,用 long long 进行存储,最后求模

代码实现

#include <bits/stdc++.h> 
using namespace std;

#define MAXLEN 100009	/* 100009太大了,编译器可能报错,
						编译时改小,代码提交时要改回来 */ 
typedef long long ll;

ll a[MAXLEN
### 第15届蓝桥杯C/C++B真题概述 第15届蓝桥杯C/C++B的比难度有所提升,旨在更全面地评估参者的编程能力和逻辑思维能力。以下是该事的部分典型题目及其解题思路: #### 握手问题 此题可以通过两种方求解: - **合数学**:利用排列合的知识计算可能的握手次数。 - **暴力枚举**:通过遍历所有可能性来统计握手情况。 #### 小球反弹 对于小球反弹的问题,主要关注的是物理运动学中的反射原理以及边界条件处理[^2]。 #### 好数算法 采用暴力解法即可解决问题,并且在此场景下不会导致超时现象发生。具体实现涉及对给定范围内的整数逐一检验其是否满足特定性质。 #### R格式转换 R格式相关题目通常涉及到字符串操作或者模式匹配等内容,在解答这类问题时需注意输入输出格式的要求严格遵循题目描述。 #### 宝石合 应用唯一分解定理作为核心理论依据来进行设计解决方案,重点在于如何有效地将大数值拆分成若干质因数乘积形式并据此构建合理的算法框架。 #### 数字接龙游戏 运用深度优先搜索(DFS)策略探索所有可行路径直至找到符合条件的结果序列为止;期间要注意剪枝优化以提高效率减少不必要的运算量。 #### 拔河比安排 考虑团队成员力量分配均衡性等因素影响最终胜负关系,从而制定相应的模拟过程或贪心则指导下的决策流程。 以上即为部分公开可得之第15届蓝桥杯C/C++B试题概览及对应解析方向。 ```cpp // 示例代码片段展示了一个简单的好数判断程序 #include <iostream> using namespace std; int main(){ int n; cin >> n; bool isGoodNumber = true; while(n != 0){ int digit = n % 10; if(digit == 3 || digit == 4 || digit == 7){ isGoodNumber = false; break; } n /= 10; } cout << (isGoodNumber ? "Yes" : "No") << endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值