由于数字顺序不影响乘积,所以最优解可以定为两个非递减数字,以此利用dfs开始暴力枚举最大18位的数字。
附本人ac码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define mod 998244353
const ll N=1e6+10;
struct num
{
ll n;
ll ji;
int s;
//先按变换次数从大到小,再按数字从小到大
bool operator<(const num &t) const{
if (t.s !=s) {
return t.s < s;
}
return t.n > n;
}
};
map<ll,int>mp;// 缓存计算结果
vector<num>a;// 存储候选数字
ll f(ll x) // 计算数字各位数字的乘积
{
ll res=1;
string s=to_string(x);
for(char it:s)
{
int n=it-'0';
res*=n;
}
return res;
}
int g(ll x)
{
if(x<10)return 0;// 如果已经是1位数,不需要再变换
if(mp.find(x)!=mp.end())// 如果已经计算过,直接返回缓存结果
{
return mp[x];
}
ll next=f(x);
int steps=1+g(next);// 递归计算,并缓存结果
mp[x]=steps;
return steps;
}
void dfs(int length,ll number,ll product,int digit)// 生成所有可能的数字组合
{
if(length>0)
{
int steps=0;
if(number>=10)
{
steps=1+g(product);
}
a.push_back({number,product,steps});
}
if(length==18)return;// 如果已经达到18位,停止生成
for(int i=digit;i<=9;i++)
{
dfs(length+1,number*10+i,product*i,i);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
for(int i=2;i<=9;i++)// 从2-9开始生成所有数字组合
{
dfs(1,i,i,i);
}
sort(a.begin(),a.end());
num A=a[0],B;
for(int i=1;i<a.size();i++)// 寻找第一个数字乘积不同的候选
{
if(a[i].ji!=A.ji)
{
B=a[i];
break;
}
}
cout<<A.n<<" "<<B.n;
return 0;
}

京公网安备 11010502036488号