欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

7-1 整数分解为若干项之和(20 分)用递归求解(C语言实现)

程序员文章站 2022-03-23 09:44:59
...

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

将一个正整数N分解成几个正整数相加,可以有多种分解方法,例如7=6+1,7=5+2,7=5+1+1,…。编程求出正整数N的所有整数分解式子。
输入格式:
每个输入包含一个测试用例,即正整数N (0<N≤30)。
输出格式
按递增顺序输出N的所有整数分解式子。递增顺序是指:对于两个分解序列N​1​​={n​1​​,n​2​​,⋯}和N​2​​={m​1​​,m​2​​,⋯},若存在i使得n​1​​=m​1​​,⋯,n​i​​=m​i​​,但是n​i+1​​<m​i+1​​,则N​1​​序列必定在N​2​​序列之前输出。每个式子由小到大相加,式子间用分号隔开,且每输出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
下面是代码部分

#include <stdio.h>
int a[30]={0},sum=0,n,print_count=0;
//全局变量;数组a用来存储分解后的各项 ,
//sum用来表示在分解过程中各项的值当前相加的和,print_count 用来表示当前打印了多少次(用于每四次换行)** 
void Print()
{
	print_count++;
	printf ("%d=",n);
	for (int i=1;a[i]!=0;++i)
	{
		if (a[i+1]==0&&print_count%4==0)printf("%d\n",a[i]);//最后一项的处理 (最后一项输出完需要换行时) 
		else if (a[i+1]==0&&i==1)printf ("%d",a[i]);//最后一项输出完,以后再没有输出却不需要换行时(即输出n=n时) 
		else if (a[i+1]==0)printf ("%d;",a[i]);//其他正常情况最后一项处理 
		else printf ("%d+",a[i]);//非最后一项的处理 
	 } 
 } 
 void dividing_recursion_f(int j)
 //递归函数:边界有两个 (1) 开始调用时sum的值正好等于n,此时不用往下进行了直接输出然后结束就可以了
 //第二个结束标志是for循环中sum+i值大于n   此时表示第j项以后不会再有符合要求的项了,此时只需结束--返回就行了 
 //参数j用于表示分解的第j项 
 {
 	if (sum==n){
 		Print();//边界(1) 
 		return ;
	}
 	for (int i=1;i<=n;i++)//for循环用于不断用数去试 
 	{//核心部分 :当sum+i小于n时 且 前一项要比待填入的分解项(i)大时才填入(a[j]=i)(别忘了sum要加起来) 
 	//接下来的操作就是通过递归调用来填入下一分解项(j+1)调用结束后要复原 
 		if (sum+i<=n&&a[j-1]<=i){
 			a[j]=i;sum+=a[j];
 			dividing_recursion_f(j+1);
 			sum-=a[j];a[j]=0;//复原操作 
		 }
		else if(a[j-1]>i)continue;//注意这一个判断很重要,用来判断前一项是否大于待插入的项,
								//大于就continue,循环进行下一次 ;该判断用于处理类似3=1+2;3=2+1等重复的情况 
		else{//这个else是处理出现了sum+i>n的情况,此时是递归边界(2) 
			return ;
		}
	 }
 }
 int main ()
 {
 	scanf ("%d",&n);
 	dividing_recursion_f(1);
 	return 0;
 }