[CSP-S模拟测试]:A(数学)

题目传送门(内部题44)


输入格式

一行四个整数,分别表示$S,T,a,b$。


输出格式

输出最小步数,数据保证有解。


样例

样例输入:

10 28 4 2

样例输出:

2


数据范围与提示

样例解释:

先使用$1$操作,再使用$2$操作。

数据范围:

对于$30\%$的数据:
$T\leqslant {10}^6$
另外$30\%$的数据:
$a=1$
对于所有数据:
$1\leqslant S<T\leqslant {10}^{18}$
$1\leqslant a\leqslant {10}^{18}$
$2\leqslant b\leqslant {10}^{18}$


题解

我们可以将$T$拆解为$S\times b^n+m\times a$,进而$m=\frac{T-S\times b^n}{a}$。

那么我们可以枚举乘法的次数,然后看是否可行。

至于如何求出加法的次数,贪心就好了。

时间复杂度:$\Theta(\log^2T)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
long long S,T,a,b;
long long ans=1LL<<60;
long long B[65];
long long top;
int main()
{
	scanf("%lld%lld%lld%lld",&S,&T,&a,&b);
	B[0]=1;
	for(long long i=b;i<=T;i*=b)B[++top]=i;
	for(int i=0;T-S*B[i]>0;i++)
		if(!((T-S*B[i])%a))
		{
			long long flag=(T-S*B[i])/a;
			long long minn=0;
			for(int j=i;j>=0;j--)
			{
				long long t=flag/B[j];
				minn+=t;
				flag-=t*B[j];
			}
			ans=min(ans,i+minn);
		}
	printf("%lld",ans);
	return 0;
}

rp++

posted @ 2019-09-19 16:38  HEOI-动动  阅读(308)  评论(0编辑  收藏  举报