注意:要求为n个不同的数之和(积)。
1.将一个自然数m分解为n个不同的自然数之和:
/*样例输入
5 2
样例输出
case: 1
1 4
===============================
case: 2
2 3
===============================
可能的结果数为:2
*/
/*样例输入
14 4
样例输出
case: 1
1 2 3 8
===============================
case: 2
1 2 4 7
===============================
case: 3
1 2 5 6
===============================
case: 4
1 3 4 6
===============================
case: 5
2 3 4 5
===============================
可能的结果数为:5
*/
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> record;
int index = 0;
void func(int m,int n,int endnum)//m为目前需分解的数,n为需分解成多少个数(个数),min_el为前面已分解了的最大的数
{
if (n == 2)
{
for(int i = endnum+1; i*2<m; ++i)
{
if(i!=m-i)
{
record.push_back(i);
record.push_back(m-i);
/*以下四行代码用于输出每组结果*/
cout << "case: " << ++index<<endl;
for(int i=0;i<record.size();i++)
cout <<record[i]<<" ";
cout <<"\n==============================="<<endl;
record.pop_back();
record.pop_back();
}
}
return;
}
for (int beg = endnum+1; beg*n<m; ++beg)//beg为当前确定了的数。beg最大为倒数第3个数(最后的两个数最大),即最后n=3,beg一定小于m/3
{
record.push_back(beg);
func(m - beg,n - 1,beg);//三个参数m-beg减掉这个当前确定了的数字后需要凑的和,n-1即为减去这个数字后剩的个数,beg为当前确定了的数字
record.pop_back();
}
}
int main()
{
int M,N;
cin>>M>>N;
func(M,N,0);
cout<<"可能的结果数为:"<<index<<endl;
return 0;
}
2.将一个自然数m分解为n个不同的自然数之积:
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
vector<int> record;
int index=0;
void fun(int m,int n,int endnum)
{
if(n==2)
{
for(int i=endnum+1;i*i<m;i++)
{
if(m%i==0&&i!=m/i)//一定要满足m能被i整除且i不等于m/i
{
record.push_back(i);
record.push_back(m/i);
cout<<"case"<<++index<<endl;
for(int i=0;i<record.size();i++)
cout<<record[i]<<" ";
cout<<"\n========================"<<endl;
record.pop_back();
record.pop_back();
}
}
return;
}
for(int beg=endnum+1;pow(beg,n)<m;beg++)//注pow(a,b)为求a的b次方,在头文件math.h中
{
record.push_back(beg);
if(m%beg==0)//若m能够被beg整除,则再m/beg递归下一次
fun(m/beg,n-1,beg);
record.pop_back();
}
}
int main()
{
int m,n;
cin>>m>>n;
fun(m,n,0);
cout<<index<<endl;
return 0;
}