Searching for Soulmates S 题解
这里的 \(x\) 可以乘 2 或除 2 或加 1 。
也相当于 \(y\) 可以除 2 或乘 2 或减 1 。
这题我们发现每一个数都是可以任意的到达另一个数。因为每一个数都可以到达 1 ,这里只需要用到除和加即可,若奇数则加,否则除。
可以让 \(x\) 做转移到 1 的过程,再从 \(y\) 这一个点到 \(x'\) 的最小距离即可这里只能使用减和除,若使用乘那还不如直接在 \(x'\) 的基础上进行继续向 1 转移。
把这个由 \(y \rightarrow x\) 的最小的距离抽象成函数 \(f(x,y)\)
-
\(x'>y\) 那\(f(x,y)=\inf\),因为这个只能除
2来减少 \(x'\) ,所以不可能转移。 -
\(2\times x'>y\) 这里我们不能做乘
2操作,只能加1操作,之后亦是如此, \(f(x,y)=y-x\) -
\(2\mid y\) \(f(x,y)=f(x,y/2)\)
-
\(2\nmid y\) \(f(x,y)=f(x,y-1)\)
这样计算 \(f\) 的时间复杂度为\(O(\log a)\) 的总的时间复杂度是 \(O(\log^2a)\) 的,代码简单。
#include<bits/stdc++.h> #define int long long using namespace std; int T,x,y,ans; int dfs(int x,int y) { if(x > y) return 1e18; if(x*2 > y) return y-x; return y&1? dfs(x,y-1)+1:dfs(x,y>>1)+1; } int cnt; signed main() { scanf("%lld",&T); while(T--) { scanf("%lld%lld",&x,&y); ans=1e18,cnt=0; do{ ans=min(ans,cnt+dfs(x,y)); cnt++; if(x&1)x++; else x/=2; } while(x>1); cout<<ans<<endl; } return 0; }

浙公网安备 33010602011771号