算法题(一)

来源:互联网 发布:淘宝如何做商品详情页 编辑:程序博客网 时间:2024/05/19 09:15

/*
 * 算法求解:
 * 把一个自然数分解成若干个互不相等的自然数之和,使这若干个数的乘积最大
 *
**/


#include <stdio.h>
#include <malloc.h>


#define TITLE  "把一自然数分解成若干个互不相等的自然数之和,使其乘积最大"
#define INPUT  "请输入一个自然数"
#define REIN   "请按指定范围重新输入"
#define OUTPUT "分解结果为"
#define MAX     10000
#define MIN     3


void main (void)
{
 int n   = 0;        // 要分解的这个自然数
 int i   = 0;        // 用来做2~i的累加
 int sum = 0;        // 保存2~i的累加和
 int m   = 0;        // n与sum之差
 int j   = 0;        // 临时变量

 printf (TITLE);
 printf ("/n/n");
 

 // 输入一个数 
 printf (INPUT);
 printf ("(%d - %d)/n", MIN, MAX);
 scanf  ("%d", &n);
 while (n < MIN || n > MAX)
 {
     printf (REIN);
     printf ("(%d - %d)/n", MIN, MAX);
     scanf  ("%d", &n);
 }


 // 如果小于5,直接输出结果并使程序结束
 if (n < 5)
 {  
  printf (OUTPUT);
  printf ("/n%d/t%d", (n - 1) / 2, n - (n - 1) / 2);
  printf ("/n/n");
  return;
 }


 // 求解: 2~i的序列,直到其总和超过或等于n
 for (sum = 2, i = 3; sum < n; i++)
 {
  sum = sum + i;
 }

   
 // 输出结果序列
 printf (OUTPUT);
 printf ("/n");

 i --; // i要还原
 if (sum == n)
 {
  // 如果2~i序列之和等于n, 直接输出该序列
  for (j = 2; j <= i; j++)
  {
   printf ("%d/t", j);
  }
 }
 else
 {
  // 2~i序列之和超过n, 则序列为2~(i-1)  
  sum -= i;
  i   -= 1;
       
  // 计算n与序列总和之差,
  m = n - sum;
  
  // 将差值分配到序列中(从后往前加1)
  for (j = 2; j < i; j++)
  {
   if (i - j + 1 > m)
   {
    printf ("%d/t", j);
   }
   else
   {
    printf ("%d/t", j + 1);
   }
  }//~ for

  // 若差值能使序列(共有i-1个数)每个数加1仍有剩余, 则最后一个数加2
  if (m < i)
  {
   printf ("%d/t", i + 1);
  }
  else
  {
   printf ("%d/t", i + 2);
  }
 }

 // 结束
 printf ("/n/n");
 return;
}