题意
给一个数(S),可以加(a)或者乘(b),问最少多少次操作到(T),无解输出-1,((1leq aleq 10^9,2leq bleq 10^9))
思路
刚刚看到像跳楼机,但是a,b较大于是放弃(说不定可以乱胡呢?);当然直接建图也有30分的好成绩(
即使(a,b)交替操作,最终状态仍然可以化成(T=S imes b^y + a imes x)的形式
枚举(y),最多不超过(logn)种,一个(y)对应一个(x),需要对(x)进行(b+1)进制拆分,且每一位加起来的数最小
从高位到低位贪心即可完成拆分操作,整个算法的时间复杂度为(O(log^2n))(maybe
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll s,t,a,b,ans=(1LL<<60);
ll qpow(ll a,ll b)
{
ll ret=1;
while(b)
{
if(b&1) ret=ret*a;
a*=a;
b>>=1;
}
return ret;
}
ll find(ll x,ll y)
{
ll ret=0;
for(int i=x;i>=0;--i)
{
ll po=qpow(b,i);
ret+=y/po;
y%=po;
}
return ret;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%lld%lld%lld%lld",&s,&t,&a,&b);
for(ll i=0;i<=32;i++)
{
ll x=t-s*qpow(b,i);
if(x<0) break;
if(x%a) continue;
ll need=x/a;
ll st=find(i,need);
if(st) ans=min(ans,i+st);
}
if(ans==(1LL<<60)) ans=-1;
printf("%lld
",ans);
return 0;
}