C++输入一个正整数 n ,返回一个最小正整数 m ( m 至少是2位数),使得 m 的各位乘积等于 n

原题目为:输入一个正整数 n ,返回一个最小正整数 m ( m 至少是2位数),使得 m 的各位乘积等于 n, 例如输入36,输出49,输入100,输出455,对于某个 n 不存在这样的 m ,请返回-1。

解决思路:

**首先如果n是负数,则不存在m直接返回:-1.
其次如果n是个位数,则m返回:10+n。

对于任意输入的n,首先使用i=2~9依次尝试是否能够整除,若能整除则在二维容器中添加一行(其实叫做一层更加合适)。**
以n = 36为例,36可以被2、4、6、9整除,即产生(2开头的)第一层,(3开头的)第二层,(4开头)的第三层,(6开头的)第四层,以及(9开头的)第五层。

我的思路中,每一层的数字必须都为小于10的个位数,因此对于能够被某一i整除,但是整除之后的结果并非小于10的数,为了把它变成个位数,需要再次用j = 2~9的数进行尝试。
仍然以n = 36为例,我们来看第二层(3开头),本来这一层应该是(3,12),但是12(程序中的:“num”)不满足本层的要求,因此用j = 2~9来尝试12可以被那些数字整除,可以得到的数字有:(2,3,4,6)。所以第二层可以取(3,2,6)或者(3,3,4)(同时要保证三个数的乘积还是n=36)

与第一次对n的处理不同,由于我们要找最小组合数m,所以事实上并不需要(2,3,4)这一组,因为226<334,比较方便的一点是当j从2取到9的过程中一定是先出现小数字,后出现大数字。那我们可以直接判断一旦这些数字已经是个位数了(比如找出了2,2,6),就停止尝试的过程,(因为再尝试下去组合的数字一定比这个大,没有必要了)。这一层就算是建立好了:n = 36时的(3开头的)第二层:(3,2,6)

这里展示所有的层(层数是动态的,上限是2开头到9开头的一共8层,不过例如36不能被7整除,就不要这层):以n = 36为例:
第一层:(2,2,9)
第二层:(3,2,6)
第三层:(4,9)
第四层:(6,6)
第五层:(9,4)

每一层在计算出来后立刻计算出本层的组合数值。然后用打擂台的方式,如果当前计算值比“初始最小值”小,则吧“初始最小值”替换为当前计算值。(我初始最小值设置的一个亿)。

例如:第一层:229 < 100000000,则最小值变为229; 第二层:326 > 229,最小值不变; 第三层:49 < 229,则最小值变为49…………………………最后比下来剩下的最小值就是要输出的m。(n = 36 时,m = 49)

代码全部贴上来,希望能给大家一些帮助;

#include 
#include 
using namespace std;

int Trans(int n) {
	if (n <= 0 ) { cout << "数据输入格式不规范"; return -1; }
	int m = 100000000, i = 0, j = 0;
	int row = 1000;
	vector<vector<int> > Factor(row,vector<int>(0));
	if (n / 10 == 0) return n+10;

	if (n / 10 != 0) {//如果n不是个位数
		for (j = 2; j < 10; j++) {
			if (n % j == 0) {
				Factor.resize(i + 1);//二维容器层数加一
				Factor[i].push_back(j);// 将第一个 个位因数放入i层
				int num = n / j;// num 18
				// 如果n/j是个位数
				if (num / 10 == 0)
					Factor[i].push_back(num);
				// 如果n/j不是个位数
				int k = 2;
				while (num/10 != 0 && k < 10) {
					if (num % k == 0) {// 查找num的因数
						Factor[i].push_back(k);// 将num的第一个个位因数放入i层
						num = num / k;
						k = 1;
					}
					if (num / 10 == 0) Factor[i].push_back(num);
					k++;
				}
				if (k == 10) return -1;//若num中存在从2到9都没有能够整除的,则不存在这样的m
				//计算当前层组成数的最小值

				int min = 0;
				for (int content : Factor[i]) {
					min += content * pow(10, Factor[i].size()-1);
					Factor[i].pop_back();
				}
				//2,18→2,2,9    【0】:229
				//与已记录的最小值比对
				if (min < m)  m = min;
				//进入下一层
				i++;
			}
		}
		if (m == 100000000) return -1;// 若从2到9都没有能够整除的,则不存在这样的m
	}
	return m;
}
int main() {
	int n,m;
	while (1) {
		cout << "请输入任意一个正整数" << endl;
		cin >> n;
		m = Trans(n);
		cout << "结果为:   " << m << endl << endl;
	}
}

你可能感兴趣的:(C++输入一个正整数 n ,返回一个最小正整数 m ( m 至少是2位数),使得 m 的各位乘积等于 n)