这其实也是个搜索组合问题,但是却可以借助动态规划的思想,将问题一步一步分解
首先来个简单点的,输出全部的可能!
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
//存储用户输入的整数
int n;
//存储用户输入的要拆分的个数
int m;
//计数器,记录拆分结果的个数
int totalKind;
//存储拆分出的因数
//注意:这里只定义了100长度的数组空间,可根据需要自己扩充
int a[100];
void print()
{
cout<<n<<" = "<<a[1];
for (int i=2; i<=m; i++)
{
cout<<" * "<<a[i];
}
//输出换行
cout<<endl;
//拆分结果个数自增
totalKind++;
}
void Split(int arrayIndex,int preDivisor,int newDivisor)
{
//判断是否拆分结束,如果结束则输出该种拆分结果
//拆分结束的条件是:
//数组下标(即拆分的因数的个数)等于用户输入的拆分个数
//并且当前因数大于前一个因数(即保证因数从小到大获取,避免重复)
if (arrayIndex==m && newDivisor>=preDivisor)
{
//存储当前(新)的因数
a[arrayIndex] = newDivisor;
//输出当前拆分结果
print(); //不是一直存储,是只要满足条件就打印
//退出该函数
return;
}
//如果拆分没有结束,则将当前(新)的因数继续拆分
for (int i=preDivisor; i<=newDivisor; i++)
{
//如果当前因数能整除当前i值
if (newDivisor%i == 0)
{
//再次获得因素
a[arrayIndex]=i;
//获得新的因数,继续拆分,递归
Split(arrayIndex+1,i,newDivisor/i);
}
}
}
int main()
{
//计数器初始化
totalKind=0;
cout<<"请输入您要拆分的整数(按回车键确认): ";
cin>>n;
//输出换行
cout<<endl;
cout<<"您要拆分成几个数的乘积(按回车键确认): ";
cin>>m;
//输出换行
cout<<endl;
cout<<"您希望的将 "<<n<<" 拆分成 "<<m<<" 个数的乘积,结果如下: "<<endl;
//输出换行
cout<<endl;
for (int i=2; i<=n; i++)
{
//如果n能整除i
if (n%i==0)
{
//存储首个因数
a[1]=i;
//将整数除以因数i后得到的因数进行拆分
Split(2,i,n/i);
}
}
//输出换行
cout<<endl;
//输出拆分结果总个数
if (totalKind == 0)
cout<<"NO"<<endl;
//输出换行
cout<<endl;
return 0;
}
现在将问题改变:输出 N = 奇数 * 偶数 且是偶数中最小的那一个!没有的话则输出NO!
这个只是对上边的改进,添加一点约束罢了!
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
//存储用户输入的整数
int n;
//存储用户输入的要拆分的个数
int m;
//计数器,记录拆分结果的个数
int totalKind;
//存储拆分出的因数
//注意:这里只定义了100长度的数组空间,可根据需要自己扩充
int a[100];
void print()
{
cout<<n<<" = "<<a[1];
for (int i=2; i<=m; i++)
{
cout<<" * "<<a[i];
}
//输出换行
cout<<endl;
//拆分结果个数自增
totalKind++;
}
void Split(int arrayIndex,int preDivisor,int newDivisor)
{
//判断是否拆分结束,如果结束则输出该种拆分结果
//拆分结束的条件是:
//数组下标(即拆分的因数的个数)等于用户输入的拆分个数
//并且当前因数大于前一个因数(即保证因数从小到大获取,避免重复)
if (arrayIndex==m && newDivisor>=preDivisor) //如果两个数的乘积到这里就结束,不进行下边的迭代了
{
//存储当前(新)的因数
a[arrayIndex] = newDivisor;
//输出当前拆分结果
print();
//退出该函数
return;
//break;
}
//如果拆分没有结束,则将当前(新)的因数继续拆分
for (int i=preDivisor; i<=newDivisor; i++)
{
//如果当前因数能整除当前i值
if (newDivisor%i == 0)
{
//再次获得因素
a[arrayIndex]=i;
//获得新的因数,继续拆分,递归
Split(arrayIndex+1,i,newDivisor/i);
}
}
}
int main()
{
//计数器初始化
totalKind=0;
cout<<"请输入您要拆分的整数(按回车键确认): ";
cin>>n;
//输出换行
cout<<endl;
cout<<"您要拆分成几个数的乘积(按回车键确认): ";
cin>>m;
//输出换行
cout<<endl;
cout<<"您希望的将 "<<n<<" 拆分成 "<<m<<" 个数的乘积,结果如下: "<<endl;
//输出换行
cout<<endl;
if ( n%2 ==0) //如果N为偶数,才进入循环
{
//for (int i=1; i<=n; i=i+2)
for (int i=n/2; i>=0; i=i-1)
{
//如果n能整除i
if (n%i==0 && i%2!=0 )
{
//存储首个因数
a[1]=i;
//将整数除以因数i后得到的因数进行拆分
Split(2,i,n/i);
}
//获取首字母最大的结果
if (totalKind >= 1)
{ break ;}
}
}
else
{//输出换行
cout<<endl;
//输出拆分结果总个数
if (totalKind == 0)
cout<<"NO"<<endl;
//输出换行
cout<<endl;
}
cout << totalKind;
return 0;
}