题目描述:
D - 桁和 / Digit Sum
Time Limit: 2 sec / Memory Limit: 256 MB
Score : 500500 points
Problem Statement
For integers b(b≥2)b(b≥2) and n(n≥1)n(n≥1), let the function f(b,n)f(b,n)
be defined as follows:
- f(b,n)=nf(b,n)=n, when n<bn<b
- f(b,n)=f(b,floor(n/b))+(n mod b)f(b,n)=f(b,floor(n/b))+(n mod b), when n≥bn≥b
Here, floor(n/b)floor(n/b) denotes the largest integer not exceeding n/bn/b, and n
mod bn mod b denotes the remainder of nn divided by bb.
Less formally, f(b,n)f(b,n) is equal to the sum of the digits of nn written in base bb.
For example, the following hold:
- f(10,87654)=8+7+6+5+4=30f(10,87654)=8+7+6+5+4=30
- f(100,87654)=8+76+54=138f(100,87654)=8+76+54=138
You are given integers nn and ss. Determine if there exists an integer b(b≥2)
such that f(b,n)=sf(b,n)=s. If the answer is positive, also find the smallest such bb.
Constraints
- 1≤n≤10111≤n≤1011
- 1≤s≤10111≤s≤1011
- n,sn,s are integers.
Input
The input is given from Standard Input in the following format:
nn ssOutput
If there exists an integer b(b≥2)b(b≥2) such that f(b,n)=sf(b,n)=s, print the
smallest such bb. If such bb does not exist, print
-1
instead.Sample Input 1 Copy
Copy
87654 30Sample Output 1 Copy
Copy
10Sample Input 2 Copy
Copy
87654 138Sample Output 2 Copy
Copy
100Sample Input 3 Copy
Copy
87654 45678Sample Output 3 Copy
Copy
-1Sample Input 4 Copy
Copy
31415926535 1Sample Output 4 Copy
Copy
31415926535Sample Input 5 Copy
Copy
1 31415926535Sample Output 5 Copy
Copy
-1
核心题意:
这题目一上来肯定先想暴力,但很明显会超时。然后这里好像有一个比较常用的技巧,就是分小于Sqrt(N)和大于等于Sqrt(N)考虑。然后根据题目给出的表达式枚举b的可能值。
其他人的理解:
代码实现:
#include<bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define io ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int N=2e5+100;
using namespace std;
int judge(LL tmp,LL n,LL s)
{
LL sum=0;
while(n)
{
sum+=n%tmp;
if(sum>s)return 0;
n/=tmp;
}
if(sum==s)return 1;
return 0;
}
int main()
{
io;
LL n,s;
while(cin>>n>>s)
{
if(n==s)
{
cout<<n+1<<endl;
continue;
}
else if(s>n)
{
cout<<-1<<endl;
continue;
}
LL f=0;
LL up=sqrt(n)+1;
for(LL i=2;i<=up;i++)
{
if(judge(i,n,s))
{
f=i;
break;
}
}
if(f)
{
cout<<f<<endl;
continue;
}
else
{
LL up=sqrt(n-s);
LL ans=999999999999999999;
for(LL i=1;i<=up;i++)
{
if((n-s)%i!=0)continue;
LL tmp=i+1;
if(judge(tmp,n,s)&&((n-s)/i)==(n/tmp))
{
f=tmp;
ans=min(ans,f);
}
else if(judge((n-s)/i+1,n,s)&&(i==n/((n-s)/i+1)))
{
f=(n-s)/i+1;
ans=min(ans,f);
}
}
if(f)cout<<ans<<endl;
else cout<<-1<<endl;
}
}
return 0;
}
The end;