C++高精度乘法实现及星系资源能量统计题解
好的,这是一个典型的**高精度乘法**问题。由于每个资源的位数可能高达100位,并且有最多100个这样的数相乘,结果会非常巨大,远超`unsigned long long`的表示范围(约20位),所以必须使用**高精度算法**来处理。 下面我将为你提供完整的C++实现方案,并详细解释核心代码。 ### 🛠 准备工作与核心思路 - **数据类型**:不能使用`int`或`long long`。我们需要用 **字符串** 或 **数组** 来存储每个资源点的数字。 - **算法**:模拟手工乘法的过程,但将其优化为: 1. 先将**第一个**高精度数存储在大数数组中。 2. 依次将**后续每个**资源数与大数数组相乘,结果仍然保存在大数数组中。 - **注意事项**:需要处理进位、去除结果前导零。 ### 📝 C++ 代码实现 以下代码使用`std::vector<int>`来存储大数的每一位(低位在前,便于计算),并定义了一个`multiply`函数来处理高精度数与常规字符串整数的乘法。 ```cpp #include <iostream> #include <string> #include <vector> #include <algorithm> // for reverse using namespace std; // 高精度乘法函数:将大数 a(存储在vector中,低位在前)乘以字符串表示的整数 b vector<int> multiply(const vector<int>& a, const string& b) { // 将字符串b转换为数字数组,低位在前 vector<int> b_digits; for (int i = b.size() - 1; i >= 0; --i) { b_digits.push_back(b[i] - '0'); } // 结果数组,长度最多为 a.size() + b.size(),初始化为0 vector<int> result(a.size() + b_digits.size(), 0); // 模拟乘法过程 for (int i = 0; i < a.size(); ++i) { for (int j = 0; j < b_digits.size(); ++j) { result[i + j] += a[i] * b_digits[j]; // 处理进位 if (result[i + j] >= 10) { result[i + j + 1] += result[i + j] / 10; result[i + j] %= 10; } } } // 去除前导零(但保留至少一位数字,如果结果全是0则保留一位) while (result.size() > 1 && result.back() == 0) { result.pop_back(); } return result; } int main() { int n; cin >> n; // 读取第一个数字,初始化大数 string firstNum; cin >> firstNum; // 将第一个大数转换为vector,低位在前 vector<int> bigNum; for (int i = firstNum.size() - 1; i >= 0; --i) { bigNum.push_back(firstNum[i] - '0'); } // 依次乘以剩下的 n-1 个数字 for (int i = 1; i < n; ++i) { string nextNum; cin >> nextNum; bigNum = multiply(bigNum, nextNum); } // 输出结果:高位在前 for (int i = bigNum.size() - 1; i >= 0; --i) { cout << bigNum[i]; } cout << endl; return 0; } ``` ### 🔍 代码关键点解释 1. **`vector<int>` 的存储方式**: - 我们采用**低位在前**(即 `a[0]` 存个位)存储。例如整数 `123` 存储为 `[3, 2, 1]`。这样做的好处是:当计算过程中位数增加,直接在数组尾部 `push_back` 即可,效率高。 2. **核心乘法 `result[i+j] += a[i] * b[j]`**: - 这是高精度乘法的核心公式。它模拟了手工乘法的竖式计算,`i+j` 是乘积结果应该放的位置(幂次)。 3. **进位处理**: - 在每次累加后立即检查是否大于等于10,并进行进位,这样可以防止中间结果溢出(尽管`int`在此场景下一般不会溢出,但这是规范写法)。也可以选择在最后统一进位,但**边乘边进位**更直观,且能防止`result`中间值过大。 4. **去前导零**: - 乘法计算结束后,`result`的最高位可能为0。我们用`while`循环去除,但保留至少一位(比如最终结果是0,则保留一个0)。 5. **读取与转换**: - 第一个数字用于初始化`bigNum`,后续数字在循环中逐一输入并与`bigNum`相乘。 ### 💡 开发与优化建议 - **性能优化**:当前代码时间复杂度为 O(n² × m),其中 n 是数字位数,m 是数字个数。对于本题数据(n ≤ 100, 位数 ≤ 100),是完全可以接受的。如果需要更高性能(比如百万位级别),则需考虑 **FFT(快速傅里叶变换)** 或 **NTT**。 - **输入效率**:如果数据量特别大,可以使用 `ios::sync_with_stdio(false); cin.tie(0);` 来加速标准输入。 - **内存安全**:由于明确限制了位数最多100,乘100次后最多10000位,`vector` 自动管理内存,没有风险。 - **错误处理**:实际开发中,应添加对输入格式的校验,例如确保读取的字符串只包含数字字符,且非空。 - **备选方案**:如果只是做竞赛或者非常小的数字(小于20位),可以尝试 `__int128` 类型(GCC扩展),但本题目数据范围完全超出 `__int128` 的能力,所以高精度是唯一选择。 ### 📚 学习资源推荐 - **经典书籍**:《算法竞赛入门经典(第2版)》(刘汝佳)中“大整数类”一节,是极好的入门资料。 - **在线教程**:各大OJ(如POJ、洛谷)上搜索“高精度乘法”模板题,如 *POJ 1001 Exponentiation*。 - **进阶**:学习FFT进行超长整数乘法,可参考《算法导论》第30章。 --- ######[AI写代码神器 | 1446点数解答 | 2026-05-31 17:08:43]
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)401
- C++实现:计算两位正整数十位与个位数字之和(附代码详解与复杂度分析)(字节豆包 | 352点数解答 | 2026-01-16 23:00:07)96
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)368
- 用 Pandas 深度剖析数据:从读取到统计分析全流程实战(GPT | 642点数解答 | 2024-06-30 15:39:49)390
- 用 Pandas 深入分析招聘数据:从数据读取到可视化全流程解析(GPT | 1539点数解答 | 2024-06-30 15:56:50)413
- Python 实现:精确统计两数范围内素数个数,附完整代码与优化思路(阿里通义 | 292点数解答 | 2024-11-28 21:36:29)276
- Python 文件数量统计:检测当前及指定路径文件数并处理错误 (字节豆包 | 179点数解答 | 2024-12-11 13:09:13)222
- Python三关挑战:文件与文件夹数量统计及路径获取(字节豆包 | 493点数解答 | 2024-12-11 13:29:49)240
- 星际编码大赛终极对决:机械星AI与异星人激战“逆序对”统计难题(字节豆包 | 509点数解答 | 2025-04-19 17:33:00)302
- Python实现:输入5个字符统计“0”出现次数及开发注意要点(字节豆包 | 255点数解答 | 2026-01-16 14:23:30)72
- 巧用筛法!计算 N 到 M 间数的最大质因数个数(DeepSeek | 245点数解答 | 2026-01-18 12:43:51)61
- C++高效求解1到n中能同时被2和3整除的数之和(DeepSeek | 1187点数解答 | 2026-04-11 10:03:38)37