c++试题(19)

给定两个正整数m,n(m>=n!),将m拆成n个数相加:m=a(1)+a(2)+...+a(n),使之满足:a(1)<a(2)<...<a(n);
编成列出所有的拆法.
例如:若m=7,n=3则只有一种拆法:
7=1+2+4

 

分析:
int   a,b;
a=m/n;b=m%n;
1:当n小于4时
n=2:可分为a-1,a+b+1
n=3:可分为a-1,a,a+b+1;
2:当n大于4时
此时可以证明a>n(用数学归纳法)
此时m=a+a+a+....+(a+b)共n项,令a(1)=a-(n-1),a(2)=a-(n-2),....a(n-1)=a-(n-(n-1))
a(n)=a+b+1+2+...+(n-1);
这样不就满足了吗,且程序的具体实现也较简单
补充:
2应为"当n大于或等于时"

 #include "stdlib.h"
#include "stdio.h"
#include "conio.h"

int m,n,*group;//m被干的数,n干的数,group干完得出的数

void split(int start,int end,int x,int sum)//目的是实现数的抽取,即从start---end 自然数列上抽取递增的x个数,使x个自然数的和为sum.
{
 int i,j;//i j
 if(sum<0)
  return;
 if(x)
 {
  for(i=start+1;i<end;i++)
  {
   group[n-x]=i;
   if(x==1)
    split(i,end,x-1,sum-i);
            else split(i,sum/(x-1)+1,x-1,sum-i);
  }
 }
 else
 {
  if(sum==0)
  {
   for(j=0;j<n;j++)
   {
    printf("%8d",group[j]);
   }
   printf("/n");
  }
 }
}

void main()
{
 printf("Please Input m:");
 scanf("%d",&m);
 printf("Please Input n:");
 scanf("%d",&n);
 group=(int*)malloc(n*sizeof(int));
 split(0,m,n,m);
 free(group);
 // getch();
 system("pause");
}

 

#include "stdlib.h"
#include "stdio.h"

int output[10];
int m=7,n=3;

void print(int pos,int cursum,int prepos)
{
 int   i=1,max;
 int   sum=0;
 max=m-pos-cursum+1;
 if (pos==1)
 {
  if (max>=prepos)
   return;
  output[1]=max;
  for(int j=1;j<=n;j++)
   printf("%d",output[j]);
  printf("**");
  return;
 }
 else
 {
  int   e=0;
  if   (max/2>=1)
   e=max/2;
  for(i=max;i>e;i--)
  {
   if (i>=prepos)
    continue;
            output[pos]=i;
   print(pos-1,cursum+i,i);
  }
 }
}
int main(int argc,char* argv[])
{
 print(n,0,m);
 system("pause");
 return   0;
}

 

#include <stdio.h>
#include "stdlib.h"

#define   M   7
#define   N   3
int   *s;
 
void   find(int   m,   int   n);
int   main(int   argc,   char*   argv[])
{
s=new   int[M+1];
s[0]=M+1;
find(M,1);
delete   []s;
system("pause");
return   0;
}

void   find(int   m,   int   n)
{
int   i;
if   (n==N&&m<s[n-1])
{
s[n]=m;
for   (i=1;i<=N;i++)
printf("%d     ",s[i]);
printf("/n");
return;

}
else
if(n==N)
return;
for   (i=s[n-1]-1;i>0;i--)
{
if(m-i<=0)
continue;
s[n]=i;
find(m-i,n+1);

}
return;
}

 

#include   "stdafx.h"
#include   "iostream.h"
//運行效率問題的比較是重要的
void   back2(int   No,int   AllNo,int   up,int   down);

int   data[1000];
int   count,count1,m,n;

int   main(int   argc,   char*   argv[])
{
int   up,down;

cout<<"Input   m   &   n:/n";
cin>>m>>n;

for   (int   i=0;i<=n;i++)   data[i]=0;

down=m-(n-1)*n/2-n+1;
up=1;
count=0; count1=0;
back2(1,n,up,down);
cout<<"/nThe   account   is   "<<count<<"."<<endl;
return   0;
}

void   back2(int   No,int   AllNo,int   up,int   down){
if   (No<AllNo)
for(int   i=up;i<=down;i++)   {
data[No]=i;
count1+=data[No];
if(count1>m)   break;
back(No+1,AllNo,data[No]+1,down+1);
}
else{
data[No]=m-count1;
if   (data[No]<=data[No-1])   return;
//if   (count1==m)  
{
for(int   j=1;j<AllNo;j++)
                                                                              cout<<data[j]<<",";
cout<<data[j]<<"/n";
count++;      
}  
  count1-=data[AllNo-1];
}
}

#include   "afx.h"
#include   "stdlib.h"
#include   "stdio.h"
#include   "conio.h"
#define   arithmetic_2
int   m,n,*group,No;
void   split(int   start,int   end,int   x,int   sum   )
{
int   i,j;
if(m-sum<start)   return;
if(x)
{
for(i=start+1;i<end/*i+(end-i)/x*/;i++)
{
group[n-x]=i;
#ifdef   arithmetic_1
split(i,end,x-1,sum-i);
#else   if

if(x==1)
split(i,end,x-1,sum-i);
else   split(i,sum/(x-1)+1,x-1,sum-i);
#endif  
}
}
else
{
if(sum==0)
{
for(j=0;j<n;j++)
{
printf("%8d",group[j]);
}
printf("/n");
No++;
}
}
}


void   main()
{
No=0;
CTime   Begin,End;
CTimeSpan   Total;
CString   szBegin,szEnd,szTotal;
printf("Please   Input   m:");
scanf("%d",&m);
printf("Please   Input   n:");
scanf("%d",&n);
group=(int*)malloc(n*sizeof(int));
Begin=CTime::GetCurrentTime();
split(0,m,n,m);
End=CTime::GetCurrentTime();
Total=End-Begin;
printf("/nThe   Total   No:%d/n",No);
szBegin=Begin.Format("%Y-%m-%d   %H:%M:%S");
printf("/nBegin   Time:%s",(LPSTR)(LPCTSTR)szBegin);
szEnd=Begin.Format("%Y-%m-%d   %H:%M:%S");
printf("/nBegin   Time:%s",(LPSTR)(LPCTSTR)szEnd);

szTotal=Total.Format("%H:%M:%S");
printf("/nTotal   Time:%s/n",(LPSTR)(LPCTSTR)szTotal);
free(group);
// getch();

}
/*
Please   Input   m:100
Please   Input   n:4

The   Total   No:5952

Begin   Time:2001-12-19   16:42:05
Begin   Time:2001-12-19   16:42:05
Total   Time:00:00:35
Press   any   key   to   continue
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值