acm题目及我的程序(3)——正整数n的加法组合

博客介绍了ACM题目的一个实例,要求找出正整数n的所有可能加法组合,不重复。例如,对于n=6,存在13种序列,其中11种符合要求。博主分享了实现这一算法的思想和运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网上看到的acm题目,来源忘记了,现在贴出自己的算法。 

要求:

一个正整数n可以写为几个正整数的和,如:
4=4
4=3+1
4=2+2
4=2+1+1
4=1+1+1+1
输入一个正整数,找出符合这种要求的所有正整数序列(序列不重复)

算法思想:

以n=6为例,将数继序列存于a[MAXROW][6]中,且将数组a的所有值初始化为1
对数组中从irow行,jcol列开始的n阶子矩阵进行操作f(6,0,0)
初始化
count=6
j=0,newn=0;
i=0
count=n
1. 如果count>6,令a[i][jcol]=count,且将该行第jcol+1列到jcol+count-1列的值改为0;否则,退出;
2. newn=n-count
3. 如果new>1,则对从该行开始从jcol+count开始的newn阶子矩阵进行类似操作,并返回增加的行数,并将该行的前jcol个元素复制到新增加的每一行;
    否则,count=count-1,处理下一行
源代码如下:
/************************************************************************
 * 一个正整数n可以写为几个正整数的和
 * 4=4
 * 4=3+1
 * 4=2+2
 * 4=2+1+1
 * 4=1+1+1+1
 * 要求:输入一个正整数,找出符合这种要求的所有正整数序列(序列不重复)
 ***********************************************************************
*/


#include 
<stdio.h>
#include 
<string.h>

#define MAXROW 12000
#define MAXCOL 20

class AdditionCombination
{
public:
    
int a[MAXROW][MAXCOL];

public:
    AdditionCombination()
{}
    
~AdditionCombination(){}

    
void Initialize(int n);
    
int GetCombinations(int n,int irow,int jcol);
    
int DeleteValidData(int n,int count,int& validcount);
    
void display(int n,int count,int validcount);
}
;

void AdditionCombination::Initialize(int n)
{
    
for(int i=0;i<MAXROW;i++)
        
for(int j=0;j<MAXCOL;j++)
            a[i][j]
=1;
}


//在数组中从irow行,jcol列开始对n阶子矩阵进行
int AdditionCombination::GetCombinations(int n,int irow,int jcol)
{
    
if(n==2)
    
{
        a[irow][jcol]
=2;
        a[irow][jcol
+1]=0;
        
return 2;
    }


    
int j=0,newn=0;
    
int i=irow;        //from line irow
    int count=n;    //count is the number of 1 to be added

    
while(count>1)
    
{
        a[i][jcol]
=count;
        
for(j=jcol+1;j<jcol+count;j++)
            a[i][j]
=0;

        newn
=n-count;
        
if(newn>1)
        
{
            
int newi=i;
            
int newj=jcol+count;
            
int newcount=GetCombinations(newn,newi,newj);

            
//copy the front count elements of the ith line for newn-1 times
            for(int k=1;k<newcount;k++)
            
{
                
for(int t=jcol;t<newj;t++)
                    a[newi
+k][t]=a[newi][t];
            }


            i
+=newcount;
            count
--;            
        }

        
else
        
{
            i
++;
            count
--;
        }

    }


    
return i-irow+1;
}


//return the number of all addition sequence
int AdditionCombination::DeleteValidData(int n,int count,int& validcount)
{
    
int t,j;

    
for(int i=1;i<count-1;i++)
    
{
        t
=j=1;
        
while(j<n)
        
{
            
while(a[i][j]==0)
                j
++;
            
if(j>=n)
                
break;

            a[i][t
++]=a[i][j];
            a[i][j
++]=0;
        }

        a[i][t]
=0;
    }


    validcount
=count;
    
for(i=1;i<count;i++)
    
{
        
for(j=0;j<n-1;j++)
        
{
            
if(a[i][j]>0 && a[i][j+1]>0)
            
{
                
if(a[i][j]<a[i][j+1] )
                
{
                    a[i][
0]=0;
                    validcount
--;
                    
break;
                }

            }

        }

    }


    
return count;
}


void AdditionCombination::display(int n,int count,int validcount)
{
    
for(int i=0;i<count;i++)
    
{
        
if(a[i][0]==0)
                
continue;

        printf(
"   %d=%d",n,a[i][0]);
        
for(int j=1;j<n;j++)
        
{
            
if(a[i][j]==0)
                
break;
            printf(
"+%d",a[i][j]);
        }

    }

    printf(
"   count=%d   sequences number=%d ",count,validcount);
}


//显示菜单
void show_menu()
{
    printf(
"--------------------------------------------- ");
    printf(
"input command to test the program ");
    printf(
"   i or I : input n to test ");
    printf(
"   q or Q : quit ");    
    printf(
"--------------------------------------------- ");
    printf(
"$ input command >");
}


void main()
{
    
char sinput[10];
    
int n;

    show_menu();

    scanf(
"%s",sinput);
    
while(stricmp(sinput,"q")!=0)
    
{
        
if(stricmp(sinput,"i")==0)
        
{
            printf(
"  please input an integer (<21) :");
            scanf(
"%d",&n);

            AdditionCombination obj;
            obj.Initialize(n);
            
int count=obj.GetCombinations(n,0,0);
            
int validcount=0;
            obj.DeleteValidData(n,count,validcount);
            obj.display(n,count,validcount);
        }


        
//输入命令
        printf("$ input command >");
        scanf(
"%s",sinput);
    }

}

运行结果如下:

1. n=6

count=13表示所有序列个数为13,其中满足要求的序列个数为11

2. n=10

count=89表示所有序列为89个,满足要求的有42个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值