【题目网站】
【题目考点】
- 深度优先搜索
- 高精度乘法(因为N到了40)
【题目思路】
- 用枚举的方式找出放乘号的位置
- 再用高精度乘法将结果乘起来
- 重复一二步直至结束
- 打印出最大的结果
【题目答案】
#include <iostream>
#include <string>
#include <algorithm>
#include <cstring>
using namespace std;
const long long N = 450;
int n, k, ans[N], biggest[N] = {1};
string num;
void mul(int a[], int b[], int s[]){//高精度的乘法
int x = 0;
for (int i = 1; i <= b[0]; i++){
x = 0;
for (int j = 1; j <= a[0]; j++){
s[i + j - 1] += a[j] * b[i] + x;
x = s[i + j - 1] / 10;
s[i + j - 1] %= 10;
}
s[i + a[0]] = x;
}
s[0] = a[0] + b[0] - (!x);
}
void change(string str, int a[]){//将字符串转换成数组
a[0] = str.size();
for (int i = a[0]; i >= 1; i--){
a[i] = str[a[0] - i] - '0';
}
}
void print(int s[]){//输出答案
for (int i = s[0]; i >= 1; i--){
cout << s[i];
}
}
int cmp(int a[], int b[]){//比较两个高精度的大小
if(a[0] > b[0]){
return 1;
}
if (a[0] < b[0]){
return 0;
}
for (int i = a[0]; i >= 1; i--){
if (a[i] > b[i]){
return 1;
}
if (b[i] > a[i]){
return 0;
}
}
return 0;
}
void move(int a[], int b[]){//交换
b[0] = a[0];
for (int i = 1; i <= a[0]; i++){
b[i] = a[i];
}
}
void dfs(int c, int last){//深度优先搜索
int itv = n - 1;
for (int i = last; i <= itv; i++){
ans[c] = i;//枚举乘号的位置
if (c < k){
dfs(c + 1, i + 1);
}else{
int s1[N] = {1, 1}, s2[N] = {0};
for (int j = 1; j <= k + 1; j++){//将结果乘起来
string tmp;
int f[N] = {0};
tmp = num.substr(ans[j - 1], ans[j] - ans[j - 1]);
change(tmp, f);
mul(f, s1, s2);
move(s2, s1);
memset(s2, 0, sizeof s2);
}
if (cmp(s1, biggest) == 1){//判断结果大小
move(s1, biggest);
}
}
}
}
int main(){
cin >> n >> k;
cin >> num;
ans[k + 1] = n;
dfs(1, 1);//深度优先搜索的开头
print(biggest);//输出
return 0;
}
【常见错误】
- 第14行x没有归零
- 第13、15行顺序弄反了
- 第16行+=写成=
- 第68行没有改变参数
- 第70行s1和s2没有清零
- 第74行substr第一个参数写错了
- 第78行未清零
- 第80或81行传进move的参数传反了
(如有错误请及时通知,我会第一时间修改)
(此博客为另一个号的修订版)