你可以对数字做两种操作:
把数字除以
�
K取整
⌊
�
/
�
⌋
⌊x/K⌋。这会让数字变小,相当于在族谱里往上找父亲。
把数字变成
�
y,满足
⌊
�
/
�
⌋
�
⌊y/K⌋=x。这相当于
�
x 是
�
y 的父亲,也就是在族谱里往下找孩子。
目标:从
�
X走到
�
Y,最少要走几步?
核心思路
找"共同祖先"
算法细节
记录所有"父亲"
寻找"儿子"
举个栗子
假设
�
10
K=10,
�
123
X=123,
�
45
Y=45。
�
Y 的族谱(记录在
�
�
�
map里):
45
45(距离
0
4
4(距离
1
1,
45
45的父)
0
0(距离
2
2,
4
4的父)
�
X 去认亲:
第一轮:
�
X是
123
123。
�
Y的族谱里有
123
123吗?没有。
�
X找爸爸变成
12
12。
第二轮:
�
X是
12
12。
�
Y的族谱里有
12
12吗?没有。
�
X找爸爸变成
1
1。
第三轮:
�
X是
1
1。
�
Y的族谱里有
1
1吗?没有。
�
X找爸爸变成
0
0。
第四轮:
�
X是
0
0。
�
Y的族谱里有
0
0吗?有(距离
�
Y是
2
2步)。
计算:
�
X走了3步:
123
→
/
10
12
→
/
10
1
→
/
10
0
123
/10
12
/10
1
/10
0
�
Y走了2步
0
→
×
10
+
4
4
→
×
10
+
5
45
0
×10+4
4
×10+5
45
。
总步数:
3
+
2
5
3+2=5步。
代码实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
int T;
cin>>T;
while(T--){
int x,y,k;
cin>>x>>y>>k;
map<int,int>m;
int c=y,d=0;
while(c>0)mc=d++,c/=k;
m0=d,c=x,d=0;
int ans=INT_MAX;
while(1){
if(m.count©)ans=min(ans,d+mc);
if(!c)break;
c/=k,d++;
}
cout<<ans<<"\n";
}
return 0;
}