题意如上图所示:
思路 + 代码
我们采用
b
f
s
bfs
bfs搜索的方法,同时我们可以保证第一次到达目的数字时的步数就是答案所需的最小操作次数,因为
b
f
s
bfs
bfs是一层一层进行搜索的。
但是我们需要注意这道题中的一些细节问题:
- 对于题目当中的第二个操作,我们在移位变换的过程中要避免循环到同一个数字,所以我们可以定义一个数组来标记该数字。
- 对于每个操作,我们需要判断操作以后的数字是否有意义。当操作后的数作为字符串时的长度小于等于 N N N作为字符串时的长度时,我们认为该数有意义,如此我们才能将其存入队列进行下一次操作。
下面时代码展示(附快读板子):
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
#define ll long long
#define mem(s, i) memset(s, i, sizeof(s))
#define PII pair<int, int>
#define INF 0x7fffffff
using namespace std;
const int N = 1e8+10;
const int mod = 1e9 + 7;
ll t, n, m;
ll stp[N];
int vim[N];
queue<ll> q;
template <class T>
inline void read(T &res)
{
char c;
T flag = 1;
while ((c = getchar()) < '0' || c > '9')
if (c == '-')
flag = -1;
res = c - '0';
while ((c = getchar()) >= '0' && c <= '9')
res = res * 10 + c - '0';
res *= flag;
}
void solve()
{
cin>>n>>m;
stp[1] = 0;
q.push(1);
while(!q.empty()){
ll t = q.front();q.pop();
// cout<<t<<endl;
if(t==m){
cout<<stp[m]<<endl;
return ;
}
for(int i = 0;i < 2;i++){
if(i==0){
ll res = t*n;
if(to_string(res).length() > to_string(m).length())continue;
stp[res] = stp[t]+1;
q.push(res);
}
else{
if(t>=10&&t%10!=0){
ll res = 0;
res = t%10*pow(10,to_string(t).length()-1)+t/10;
if(to_string(res).length() > to_string(m).length())continue;
if(vim[res]==0){
vim[res]++;
stp[res] = stp[t]+1;
q.push(res);
}
}
}
}
}cout<<-1<<endl;
}
int main()
{
// cin >> t;getchar();
// while (t--)
solve();
return 0;
}