WOJ1424-整数拆分

给你一个正整数N,现在要把这个正整数拆分成若干个正整数,使得它们的和等于N,并且使得它们的积最大。也就是说把一个正整数N,拆分成k个正整数bi  (i>=1&&i<=k) 使得b1+b2+??+bk=N,并且b1*b2*??*bk最大(如果有多个拆分方案使得最大值相等,则选择k最大的方案)。 
例如: 
    拆分方案                        乘积                     
4 = 1 + 1 + 1 + 1             1 * 1 * 1 * 1 = 1 
4 = 1 + 1 + 2                   1 * 1 * 2 = 2 
4 = 1 + 3                         1 * 3 = 3 
4 = 2 + 2                         2 * 2 = 4 
4 = 4                               4 = 4 
此时有两种拆分方案的乘积都达到最大值4,此时应该选择4 = 2 + 2这种方案。 
现在给你一个正整数N (N>0&&N<=10000),请你输出那个满足题意的拆分方案。

输入格式

此题有多组测试数据,每个测试数据单独站一行,当输入为0时,结束。

输出格式

每个测试数据的输出单独占一行,在这一行中,把拆分方案中的数按从小到大的顺序输出,相邻两个数用一个空格分开。

样例输入

1
2
3
4
5
6
7
8
0

样例输出

1
2
3
2 2
2 3
3 3
2 2 3
2 3 3


/*如果不在乎是否为整数的话,那么把每份平均分为e(2.71828459045...)时,所得到的乘积是最大的,
如果要是整数的话,那么就选尽可能地靠近e的整数即可,比如3。 
具体证明请参见 http://blog.csdn.net/pathuang68/article/details/6606605
    若n<=3,无需拆分,它本身就是最大的;
    n==4,拆分为2,2; 
    若n>4, 将n表示成 3k+r(k>0, 0< = r <3)的形式,r为余数。
      case 1: r=0,可将n拆成k个3.
      case 2: r=1,将n拆成k-1个3,和2个2.
      case 3: r=2,将n拆成k个3,和1个2.*/
#include <stdio.h>
int n;
void split(int n){
    if(n<=3)
        printf("%d\n",n);
    else if(n==4) printf("2 2\n");
    else{
        int i,k,r;
        k=n/3,r=n%3;
        if(r==1){k--;r+=3;}
        if(r==2) printf("2 ");
        if(r==4)
            printf("2 2 ");
        for(i=0;i<k;i++){
        	if(i==0)printf("3");
        	else printf(" 3");
		}
        printf("\n");
    }
}
int main(){
    while(scanf("%d",&n)!=EOF){
        if(n==0)
        break;
        split(n);
    }
    return 0;
} 


猜你喜欢

转载自blog.csdn.net/lxq1071717521/article/details/77929714
今日推荐