P1249 最大乘积 ——————洛谷

题目

P1249 最大乘积
在这里插入图片描述
分析

一道高精+贪心

一个数拆的越多乘积会越大,但不要拆出1,这样浪费了
所以就2, 3, 4, 5, ~
但也不能连续的一直拆, 因为可能不够拆了
所以就可以跳出那个数 把那个数拆给前面的
大概就这样
上代码

#include<bits/stdc++.h>
using namespace std;
const int N = 500;
string f(int x) {
  char c[10], temp;
  int i = 0, j;
  do {
    c[i] = x%10+'0';
    x /= 10;
    i++;
  } while(x != 0);
  c[i] = '\0';
  for (i--, j = 0; j <= i/2; j++, i--) {
    temp = c[j];
    c[j] = c[i];
    c[i] = temp;
  }
  return c;
}
string mul(string a, string b) {
  string s;
  int A[N], B[N], C[N];
  int la = a.size(), lb = b.size();
  memset(A, 0, sizeof(A));
  memset(B, 0, sizeof(B));
  memset(C, 0, sizeof(C));
  for (int i = 0; i < la; i++) A[la-i] = a[i]-'0';
  for (int i = 0; i < lb; i++) B[lb-i] = b[i]-'0';
  for (int i = 1; i <= la; i++) {
    for (int j = 1; j <= lb; j++) {
      C[i+j-1] += A[i]*B[j];
      C[i+j] += C[i+j-1]/10;
      C[i+j-1] %= 10; 
    }
  }
  if (C[la+lb]) s += C[la+lb]+'0';
  for (int i = la+lb-1; i >= 1; i--) {
    s += C[i]+'0';
  } 
  return s;
}
int n, c = 1, ans[1001];
string s[1001], m = "1";
int main() {
  scanf("%d", &n);
  if ( n <= 4 ){
    printf ( "%d\n%d\n", n, n );
    return 0;
  }//特判,如果n小于5,自己本身就是最优解
  for (int i = 2; i <= n; i++) {
    if (n >= i) {
      ans[c++] = i;
      s[c-1] = f(i);
      n -= i;
    } else break;
  }
  for (int i = c-1; i >= 1; i++) {
    if (n > 0) {
      ans[i]++;
      s[i] = f(ans[i]);
      n--;
    }
  }
  if (n > 0) {
    ans[c-1]++;
    s[c-1] = f(ans[c-1]);
  }
  for (int i = 1; i < c; i++) {
    cout << ans[i] << " ";
    m = mul(s[i], m);
  }
  cout << endl << m;
  return 0;
}

chapter 章节

### 高精度快速幂算法的实现 高精度快速幂是指在处理极大数值时,通过特定的数据结构(如数组)来存储这些大数,并利用快速幂的思想减少乘法次数。当涉及极大的底数和指数时,普通的整型数据无法容纳结果,因此需要采用高精度计算。 #### 使用数组模拟多位数运算 为了应对超出常规变量范围的大数,在编程中通常使用数组来表示每一个较大的数字。每一位存放在数组的一个元素内,从而能够灵活地扩展长度以适应更大的数值需求[^2]。 ```cpp #include <iostream> using namespace std; const int MAXN = 1e4 + 5; int res[MAXN], base[MAXN]; void multiply(int a[], int &len_a, int b) { int carry = 0; for (int i = 0; i < len_a || carry; ++i) { if (i < len_a) carry += a[i] * b; a[i] = carry % 10; carry /= 10; len_a = max(len_a, i + 1); } } // 计算a^b并将结果保存至res[]中,len_res为结果的实际位数 void highPrecisionPower(int a, int b, int res[], int &len_res) { memset(res, 0, sizeof(res)); res[0] = 1; len_res = 1; while (b > 0) { if (b & 1) // 如果当前二进制位为1,则累乘base到最终结果 multiply(res, len_res, a); multiply(base, len_res, a); // 更新基数 b >>= 1; // 右移一位继续判断下一个二进制位 } } ``` 这段代码展示了如何基于数组完成一次完整的高精度快速幂过程。`multiply()`函数负责两个大整数之间的相乘操作;而`highPrecisionPower()`则实现了核心逻辑——即按照快速幂的方式逐步构建目标值并将其储存在`res[]`数组之中[^3]。 #### 结合模运算优化空间性能 考虑到实际应用场景可能还会伴随取模的要求,可以在每次中间结果生成之后立即执行 `% mod` 来保持数值规模可控,进而节省内存消耗以及加速后续迭代速度: ```cpp long long fast_power_mod(long long a, long long b, long long m){ long long result = 1LL; a %= m; while(b>0){ if((b&1)==1){result=(result*a)%m;} a=((a%m)*(a%m))%m;b>>=1; } return result; } ``` 此版本不仅适用于较小范围内直接返回单个 `long long` 类型的结果,而且也支持更大规模下的高效计算。每当遇到新的乘积项都会立刻对其应用模运算,确保不会溢出同时维持较低时间复杂度 O(log n)[^5]。 #### 应用实例分析 例如 P1045《麦森数》一题就是典型的高精度快速幂的应用案例之一。该题目要求求解形如 \(M_p = 2^p - 1\) 的梅森素数形式的最大前缀,并输出其最后五百位。由于 p 值较大,直接暴力求解显然不可行,此时就需要借助上述提到的技术手段来进行有效解答[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值