版权声明:本文为博主原创文章,可以转载但是必须声明版权。 https://blog.csdn.net/forever_shi/article/details/83278036
题意:
给你一个n一个s,问你是否存在一个进制使得n在x进制下的各个位之和是s。n,s<=1e11。
题解:
乍一看确实没什么好办法,只会暴力枚举进制判断。
这题其实并没有用到什么更高明的判断方法,但是优化了枚举。
这里用到了一种经常会见到但是又很巧妙的思想:对于小于等于 的和大于 的进行分类讨论。
对于小于等于 的情况,我们只需要暴力判断即可。我们考虑该进制大于 的情况,应该有 ,其中 为进制。两式相减可以得到: ,由此可知, 是 的因子,于是我们用 的时间对 进行因数分解,对于每个因数进行暴力判断就可以了。如果没有解就输出-1。
代码:
#include <bits/stdc++.h>
using namespace std;
long long n,s;
inline long long f(long long b,long long n)
{
if(n<b)
return n;
return f(b,n/b)+n%b;
}
int main()
{
scanf("%lld%lld",&n,&s);
if(s==n)
{
printf("%lld\n",n+1);
return 0;
}
if(s>n)
{
printf("-1\n");
return 0;
}
for(long long i=2;i<=sqrt(n)+1;++i)
{
if(f(i,n)==s)
{
printf("%lld\n",i);
return 0;
}
}
long long ji=n-s,ans=1e11;
for(long long i=1;i*i<=ji;++i)
{
if(ji%i==0)
{
long long b=ji/i+1;
if(f(b,n)==s)
ans=min(ans,b);
}
}
if(ans==1e11)
printf("-1\n");
else
printf("%lld\n",ans);
return 0;
}