将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,…。编程求出正整数N的所有整数分解式子。
输入格式:
每个输入包含一个测试用例,即正整数N (0<N≤30)。
输出格式:
按递增顺序输出N的所有整数分解式子。递增顺序是指:对于两个分解序列N1={n1,n2,⋯}和N2={m1,m2,⋯},若存在i使得n1=m1,⋯,ni=mi,但是ni+1<mi+1,则N1序列必定在N2序列之前输出。每个式子由小到大相加,式子间用分号隔开,且每输出4个式子后换行。

输入样例:
7
输出样例:
7=1+1+1+1+1+1+1;7=1+1+1+1+1+2;7=1+1+1+1+3;7=1+1+1+2+2
7=1+1+1+4;7=1+1+2+3;7=1+1+5;7=1+2+2+2
7=1+2+4;7=1+3+3;7=1+6;7=2+2+3
7=2+5;7=3+4;7=7

分析
完成此样例的流程:1.不管输入的数是多大,第一个输出结果总是一串1,长度为输入的数的值,因此我们需要一个长度为n的数组(n为输入数的大小)装载输出结果,每成功装载一次,就输出。2.观察输入样例,我们发现:1+1+1+1+1+1+1,变为1+1+1+1+1+2,只需要把前式中最右边的1与右边第二个1相加,同时数组长度减一;1+1+1+1+1+2变为1+1+1+1+3,只需要把2与旁边的1相加,同时数组长度减一;1+1+1+1+3变为1+1+1+2+2,因为3-1等于2,2大于1,所以把将3左边第一个数增加一,3减为2;1+1+1+2+2变为1+1+1+4,因为2-2等于0小于2,所以把最右边的2与左边的2相加,数组长度减一;1+1+1+4变为1+1+2+3,因为4-1等于3,3大于1,同时小于4,所以4旁边的数加一,4减一;1+1+2+3变为1+1+5,因为3-2等于1,1小于2,所以将3与2相加;1+1+5变为1+2+2+2,因为5-1等于4,4大于3,所以在5左边的第一个数加一,同时根据题目要求(按递增顺序输出),我们要使数组尽量变长,并获得新的数组的长度!因此从第一个2开始,后面的数都不能小于2。1+2+2+2变为1+2+4,因为最右边两个2相减等于0,0小于2,所以把最右边的2与右边第二个2相加;1+2+4变为1+3+3,因为4减2等于2,2大于1,所以在4的右边第一个数加1……直到数组长度变为1(也就是出现n=n)。

代码展示如下:

#include<stdio.h>void output(int* a,int len);void output(int* a,int len)
{int i=0;for(i=0;i<len;++i)if(i==0)printf("%d",a[i]);elseprintf("+%d",a[i]);return;
}
int main(void)
{int n=0,i=0,len=0,origin=0,count=0,temp=0;int leap=1;int a[31]={0};scanf("%d",&n);len=n;origin=len;for(i=0;i<len;++i)a[i]=1;for(;;){up: if(leap!=1)printf(";");leap=0;printf("%d=",n);output(a,len);++count;if(count==4){printf("\n");count=0;leap=1;}if(a[0]==n)break;if(a[len-1]-a[len-2]>=4){++a[len-2];if(a[0]==n)goto up;--a[len-1];temp=a[len-1];for(i=len-1;i<origin;++i){if((temp-a[len-2])<a[len-2]&&temp-a[len-2]!=0){a[i]=temp;len=i+1;temp=0;goto up;}a[i]=a[len-2];temp=temp-a[len-2];if(temp==0){len=i+1;goto up;}}}if(a[len-1]==a[len-2]||(a[len-1]-a[len-2]==1)){a[len-2]+=a[len-1];--len;if(a[0]>n)goto end;}else{a[len-1]-=1;a[len-2]+=1;if(a[0]>n)goto end;}}
end:return 0;
}

此算法比用传统方法(递归方法)要快,如果被分解的整数是60以上,差距会非常明显。同时本人发现可以改进此算法,即不使用自定义函数,改进后的算法还要更快,如果被分解的整数是60以上,差距会非常明显。

改进后的代码展示如下:

#include<stdio.h>int main(void)
{int n=0,i=0,len=0,origin=0,count=0,temp=0;int leap=1;int a[30]={0};scanf("%d",&n);len=n;origin=len;for(i=0;i<len;++i)a[i]=1;for(;;){up: if(leap!=1)printf(";");leap=0;printf("%d=",n);for(i=0;i<len;++i)if(i==0)printf("%d",a[i]);elseprintf("+%d",a[i]);++count;if(count==4){printf("\n");count=0;leap=1;}if(a[0]==n)break;if(a[len-1]-a[len-2]==1&&len==2){a[len-2]+=a[len-1];--len;goto up;}if(a[len-1]-a[len-2]>=4){++a[len-2];if(a[0]==n)goto up;--a[len-1];temp=a[len-1];for(i=len-1;i<origin;++i){if((temp-a[len-2])<a[len-2]&&temp-a[len-2]!=0){a[i]=temp;len=i+1;temp=0;goto up;}a[i]=a[len-2];temp=temp-a[len-2];if(temp==0){len=i+1;goto up;}}}if(a[len-1]==a[len-2]||(a[len-1]-a[len-2]==1)){a[len-2]+=a[len-1];--len;if(a[0]>n)goto end;}else{a[len-1]-=1;a[len-2]+=1;if(a[0]>n)goto end;}}
end:return 0;
}

总结:改进后的算法解决了调用函数耗费时间的问题,是一个非常高效的算法。

7-14 整数分解为若干项之和 (15分)(附详细讲解(不用递归的高效算法))相关推荐

  1. 7-37 整数分解为若干项之和 (20 分)(dfs)

    7-37 整数分解为若干项之和 (20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入格式: ...

  2. 整数分解为若干项之和

    7-37 整数分解为若干项之和 (20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入格式: ...

  3. 7-37 整数分解为若干项之和(20 分)

    7-37 7-37 整数分解为若干项之和(20 分) 将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,-.编程求出正整数N的所有整数分解式子. 输入 ...

  4. 整数分解成若干项之和(DFS)拓展延伸

    在深度优先搜索的例题中,有一种题型是整数分解成若干项之和. 例如将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=1+6,7=2+5,7=1+1+5,-.编程求出正整数N的所有整数分解式 ...

  5. 整数分解为若干项之和python_SVD奇异值分解及Python实例

    1. 普通方阵的矩阵分解(EVD) 我们知道如果一个矩阵 A 是方阵,即行列维度相同(mxm),一般来说可以对 A 进行特征分解: 其中,U 的列向量是 A 的特征向量,Λ 是对角矩阵,Λ 对角元素是 ...

  6. 求整数的位数及各位数字之和 (15 分)

    7-48 求整数的位数及各位数字之和 (15 分) 对于给定的正整数N,求它的位数及其各位数字之和. 输入格式: 输入在一行中给出一个不超过109的正整数N. 输出格式: 在一行中输出N的位数及其各位 ...

  7. 实验4-1-4 求整数的位数及各位数字之和 (15 分)

    实验4-1-4 求整数的位数及各位数字之和 (15 分) 对于给定的正整数N,求它的位数及其各位数字之和. 输入格式: 输入在一行中给出一个不超过109的正整数N. 输出格式: 在一行中输出N的位数及 ...

  8. R7-5 求矩阵各行元素之和 (15 分)

    R7-5 求矩阵各行元素之和 (15 分) 本题要求编写程序,求一个给定的m×n矩阵各行元素之和. 输入格式: 输入第一行给出两个正整数m和n(1≤m,n≤6).随后m行,每行给出n个整数,其间 以空 ...

  9. 实验4-1-6 求分数序列前N项和 (15 分)

    实验4-1-6 求分数序列前N项和 (15 分) 本题要求编写程序,计算序列 2/1+3/2+5/3+8/5+- 的前N项之和.注意该序列从第2项起,每一项的分子是前一项分子与分母的和,分母是前一项的 ...

最新文章

  1. Atitit.Java exe bat  作为windows系统服务程序运行
  2. KNNClassifier
  3. linux-Apache权限限制IP端口域名+DNS域名解析
  4. Windows SharePoint Services To Be Open Source With 2007 Microsoft Office Release
  5. 记录一下所了解的一些第三开源框架
  6. 笔记(2)-文本挖掘与机器学习
  7. python 中gcd用法_Python中while语句的基本用法不了解一下嘛?
  8. 微信小游戏 UserInfoButton 获取用户信息
  9. JavaWeb项目-图书管理系统
  10. APP移动端自动化测试框架
  11. docker 启动 redis cluster,使用出现CLUSTERDOWN Hash slot not served(redis cluster重新分配slot)
  12. win7定时关机命令_如何让win7操作系统实现定时关机,以防我们忘记电脑关机
  13. sample函数注意事项
  14. oracle.exe占用cpu太高,360tray.exe占用CPU过高,怎么办
  15. 2022你不容错过的软件测试项目实战(APP项目实战)免费版
  16. 牛客 小米校招 计算题 单调栈 接雨水
  17. 百度地图api实现的定位,导航,附近搜索
  18. C. Hilbert's Hotel
  19. 阿里云(AliCloud)简介
  20. STM32----FLASH和EEPROM的区别

热门文章

  1. python3 md5源码实现(没有调库)适合用作密码学(实验)作业
  2. npm 编译报错extract:echarts:sillextract echarts@^4.2.0-rc.2 extracted to
  3. HTML5-----网页结构
  4. ajax请求时清除浏览器缓存,js清除浏览器缓存的几种方法
  5. 时序数据库如何支持秒级上亿数据的查询分组和聚合运算
  6. 【一日一logo_day_23】五角星
  7. 工作时段禁用相机功能的Android App设计与实现
  8. 太巧了!学霸夫妻携手进入武大读博,两人的硕士导师也是一对夫妻
  9. Arduino pro mini upload (使用FT232R)
  10. SuperMap Deskpro.NET 6R