给定两个正整数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
*/