题目描述:
东东在玩游戏“Game23”。
在一开始他有一个数字n,他的目标是把它转换成m,在每一步操作中,他可以将n乘以2或乘以3,他可以进行任意次操作。输出将n转换成m的操作次数,如果转换不了输出-1。
Input:
输入的唯一一行包括两个整数n和m(1<=n<=m<=5*10^8).
Output:
输出从n转换到m的操作次数,否则输出-1.
sample input:
120 51840
sample output:
7
个人思路:
对于当前的n,他想要通过给定的两个操作转化成m,那么如果 n!=m ,第一步只能是 n*=2 或者 n*=3,那么对于之后的状态依然是这样。是一个递归的算法,直到n == m;
优化:
因为通过不同的操作可能会在有限步之后的到相同的结果,例如 n * 2 * 3 = n * 3 * 2,这两种状态是相同的,但是是经过不同的步骤的得到,所以这种重复计算需要减掉。
措施:
我用了set去重,判断每一步得到的结果是否在set中,如果是就退出,否则插入进set中。
代码块:
#include <iostream>
#include <set>
using namespace std;
long long n, m;
long long d1 = 2, d2 = 3;
long long cnt = 0, fnum = -1;
set<long long>st;
void solve(long long p){
if(p == m) {
fnum = cnt;
return;
}
else if(p > m){
return;
}
if(st.count(p) == 0){
cnt++;
st.insert(p);
solve(p*d1);
solve(p*d2);
cnt--;
}
}
int main() {
cin >> n >> m;
solve(n);
cout << fnum << endl;
return 0;
}