Problem Statement
For integers b(b≥2) and n(n≥1), let the function f(b,n) be defined as follows:
- f(b,n)=n, when n<b
- f(b,n)=f(b, floor(n⁄b))+(n mod b), when n≥b
Here, floor(n⁄b) denotes the largest integer not exceeding n⁄b, and n mod b denotes the remainder of n divided by b.
Less formally, f(b,n) is equal to the sum of the digits of n written in base b. For example, the following hold:
- f(10, 87654)=8+7+6+5+4=30
- f(100, 87654)=8+76+54=138
You are given integers n and s. Determine if there exists an integer b(b≥2) such that f(b,n)=s. If the answer is positive, also find the smallest such b.
Constraints
- 1≤n≤1011
- 1≤s≤1011
- n, s are integers.
Input
The input is given from Standard Input in the following format:
n s
Output
If there exists an integer b(b≥2) such that f(b,n)=s, print the smallest such b. If such b does not exist, print -1
instead.
Sample Input 1
Copy
87654 30
Sample Output 1
Copy
10
一道看题解废了九牛二虎之力才看懂的数论题,感觉这个世界没有数学渣渣的容身之地OTZ
题意大意是给出来一个数字n,他在b进制下各位数的和为s,现在给出n和s ,求最小的数字b
【这里贴一下其他博客的计算图←一个不会敲公式的渣渣,原地址点击这里】
而后是代码,思路基本上是先调用check函数遍历所有的小于根号n的b值,如果有结果,直接return 0 就可以结束了(毕竟是寻找最小值),若找不到结果,继续进行下一步判断。
若s=n,毫无疑问这个b进制在大于n的情况下都可以,而最小值是n+1
若s>n,那么不存在这样一个b使结果成立。
然后遍历大于根号n的情况
这里就是我一直死活没有看懂的地方,现在得出来的自己的理解似乎是说的过去的,但是并不完全确定是否正确,还需要再进一步的去仔细想想。
在b>=根号n的时候,此时x1可以表示为 根号n/(b-1),由此可以确定其范围大约为 n-s/(根号n-1)+1←因为这个下取整,然后进行遍历【此处原博客代码n-s/根号n,一直没有搞懂为什么他没有这个-1,但是我加上这个-1之后运行也AC,但是不知道对方是图简单还是另有我不知道的深意】,最后进行判断,若满足条件,则输出结果,否则输出-1
#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
#include<sstream>
#include<cstring>
#include<algorithm>
#include<string>
#define LL long long
using namespace std;
LL n,s,b;
bool check(LL n, LL b)
{
long long res = 0;
while(n > 0)
{
res += n%b;
n/=b;
}
return res == s;
}
int main()
{
//int n,s,b;
cin >> n >> s;
LL temp = (LL)sqrt(n)+1;
for(LL i = 2; i <= temp; i ++)
{
if(check(n,i))
{
cout << i << endl;
return 0;
}
}
if(s == n)
{
cout << n+1 << endl;
return 0;
}
if(s > n)
{
cout << "-1" << endl;
return 0;
}
LL temp1 = n - s, temp2 = temp1/(temp-1) + 1;
for(int i = temp2; i >= 1; i --)
{
if(!(temp1%i) && s - i <= temp1/i && s >= i && i<= temp1/i)
{
cout << temp1/i + 1 << endl;
return 0;
}
}
cout << "-1" << endl;
return 0;
}