思路源于Will_Lee_Buaa
#include <iostream>
using namespace std;
int NumLen(int x){//统计位数
int len = 0;
while (x>0){
len++;
x /= 10;
}
return len;
}
void Init(int* a, int x){//作初始化
int min = 10;
int max = 0;
int num = 0;
int tend = 0;
while (x > 0){
tend = x % 10;
x /= 10;
num += tend;
if (tend > max){
max = tend;
}
if (tend < min){
min = tend;
}
}
a[0] = INT_MAX;//存放最小圈乘次数
a[1] = num;//存放各位数之和
a[2] = min;//存放最小的数
a[3] = max;//存放最大的数
}
int main(){
int x = 3;
int k = 12;
int n = NumLen(x);//表示x的位数
int m = 81 * n + 9;//b最小可以2为数组合,最大为9,最小为9.所以(x的各位数相加)*9+9;x的各位数相加最大为9*n;
if (m < 177){//因为y可能是2位数,导致1位数的x圈乘后的结果为2位数
m = 177;
}
if (k>m){//若k大于x的最大圈乘数则退出
return -1;
}
int** r = new int*[m+2];//建立二维数组
for (int i = 0; i < m + 1; i++){//遍历每
r[i] = new int[4];
Init(r[i],i);
}
r[m + 1] = new int[4];
Init(r[m + 1], x);//将起始x写到数组的最后
r[m + 1][0] = 0;//变成自己不需要圈乘
cout << "OK" << endl;
//开始操作
int flag = 1;
while (flag){//不断在序列中更新
flag = 0;
for (int i = 1; i <= m + 1; i++){//寻找X
if (r[i][0] < INT_MAX){
for (int j = 1; j <= m + 1; j++){//寻找Y
if (r[j][0] < INT_MAX){
int tend = r[i][1] * r[j][3] + r[j][2];//计算圈乘结果
if (r[tend][0]>r[i][0]+r[j][0]+1){//与原来的圈乘生产该数的次数对比找最小
flag = 1;//若有变化则更新x的寻值
r[tend][0] = r[i][0] + r[j][0] + 1; //r[i][0]为得到x的圈乘次数,r[j][0]位得到y的圈乘次数
}
//endif
}
//endif
}
}
//endif
}
}
cout << r[k][0] << endl;
return 0;
}