题目描述
从文件中读入一个正整数n(10≤n≤31000)。要求将n写成若干个正整数之和,并且使这些正整数的乘积最大。
例如,n=13,则当n表示为4+3+3+3(或2+2+3+3+3)时,乘积=108为最大。
输入格式
只有一个正整数:n (10≤n≤31000)
输出格式
第1行输出一个整数,为最大乘积的位数。
第2行输出最大乘积的前100位,如果不足100位,则按实际位数输出最大乘积。
(提示:在给定的范围内,最大乘积的位数不超过5000位)。
输入输出样例
输入 #1
13
输出 #1
3 108
#include <bits/stdc++.h>
using namespace std;
typedef double D;
const int N = 16500;
const D PI = acos(-1.0);
struct cox{
D x, y;
cox(D xx = 0, D yy = 0){x = xx; y = yy;}
}a[N], b[N];
cox operator +(const cox &u, const cox &v){
return cox(u.x + v.x, u.y + v.y);
}
cox operator -(const cox &u, const cox &v){
return cox(u.x - v.x, u.y - v.y);
}
cox operator *(const cox &u, const cox &v){
return cox(u.x * v.x - u.y * v.y , u.x * v.y + u.y * v.x);
}
int n , rnk[N], c[N], len = 16384, cn = 13;
void fft(cox *t, int op){
for (int i = 0; i < len; i++) if (i < rnk[i]) swap(t[i], t[rnk[i]]);
for (int i = 1; i < len; i <<= 1){
cox wn(cos(PI / i) , op * sin(PI / i));
for (int j = 0, jj = i << 1; j < len; j += jj){
cox w (1, 0);
for (int k = 0; k < i; k++, w = w * wn){
cox r = t[j + k], rr = w * t[i + j + k];
t[j + k] = r + rr;
t[i + j + k] = r - rr;
}
}
}
}
//fft
void po(int op){
if (op){
fft(a, 1); fft(b, 1);
for (int i = 0; i <= len; i++) a[i] = a[i] * b[i];
for (int i = 0; i <= len; i++) b[i] = b[i] * b[i];
fft(a, -1); fft(b, -1);
for (int i = 0; i <= len; i++) c[i] = (int)(a[i].x / len + 0.5);
for (int i = 0; i <= len; i++){
if (c[i] >= 10) c[i + 1] += c[i] / 10, c[i] %= 10;
}
for (int i = 0; i <= len; i++) a[i].x = c[i], a[i].y = 0, c[i] = 0;
for (int i = 0; i <= len; i++) c[i] = (int)(b[i].x / len + 0.5);
for (int i = 0; i <= len; i++){
if (c[i] >= 10) c[i + 1] += c[i] / 10, c[i] %= 10;
}
for (int i = 0; i <= len; i++) b[i].x = c[i], b[i].y = 0, c[i] = 0;
}
else{
fft(b, 1);
for (int i = 0; i <= len; i++) b[i] = b[i] * b[i];
fft(b, -1);
for (int i = 0; i <= len; i++) c[i] = (int)(b[i].x / len + 0.5);
for (int i = 0; i <= len; i++){
if (c[i] >= 10) c[i + 1] += c[i] / 10, c[i] %= 10;
}
for (int i = 0; i <= len; i++) b[i].x = c[i], b[i].y = 0, c[i] = 0;
}
}
int main(){
scanf("%d", &n);
if (n == 1) {puts("1"); return 0;}
if (n == 2) {puts("2"); return 0;}
if (n % 3 == 1) a[0] = 4, n -= 4;
else if (n % 3 == 2) a[0] = 2, n -= 2;
else a[0] = 1;
b[0] = 3; n /= 3;
for (int i = 0; i < len; i++) rnk[i] = (rnk[i>>1] >> 1) | ((i&1)<<cn);
for (; n; n >>= 1) po((n&1)?1:0);
int i;
for (i = len; a[i].x == 0;i--);
printf("%d\n", i+1);
if (i <= 99) for(; i>= 0;i--) printf("%d", (int)a[i].x);
else for (int j = 100; j; j--, i--) printf("%d", (int)a[i].x);
return 0;
}