题目描述
一个正整数一般可以分为几个互不相同的自然数的和,如3=1+2,4=1+3,5=1+4=2+3,6=1+5=2+4,…。
现在你的任务是将指定的正整数n分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。
输入输出格式
输入格式:
只一个正整数n,(3≤n≤10000)。
输出格式:
第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。
第二行是最大的乘积。
输入输出样例
输出样例
2 3 5
30
有趣的高精度
对于一个数,我们拆互不相同的个数越多,就应该越大
比如样例
divide mul
2 8 16
2 3 5 30
但也有特例,当n<5
2,3,4的拆分还不如自己本身
#include<stdio.h> const int MX=10001; int n,la,lb,len,ser[MX],a[MX],b[MX],c[MX]; void mul() { int lc; 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]) lc=la+lb; else lc=la+lb-1; for(int i=1;i<=lc;++i) a[i]=c[i],c[i]=0; la=lc; } void div() { int i=2; while(n>0) { if(n<=i) ser[i-1]=n; else ser[i-1]=i; n-=i; ++i; } len=i-2; if(ser[len]<=ser[len-1]) { int w=len; while(ser[len]) { w--; if(w==0) w=len-1; ser[w]++; ser[len]--; } len--; } a[1]=ser[1]; la=1; for(int j=2;j<=len;++j) { lb=0; int t=ser[j]; while(t) { b[++lb]=t%10; t/=10; } mul(); } } int main() { scanf("%d",&n); if(n<=4) { printf("%d",n); return 0; } div(); for(int i=1;i<=len;++i) printf("%d ",ser[i]); printf(" "); for(int i=la;i;--i) printf("%d",a[i]); return 0; }