桁和 / Digit Sum(AtCoder-2038)

Problem Description

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(nb))+(n mod b), when nb

Here, floor(nb) denotes the largest integer not exceeding nb, and n mod bdenotes 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≤10^11
  • 1≤s≤10^11
  • 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.

Example

Sample Input 1

87654
30

Sample Output 1

10

Sample Input 2

87654
138

Sample Output 2

100

Sample Input 3

87654
45678

Sample Output 3

-1

Sample Input 4

31415926535
1

Sample Output 4

31415926535

Sample Input 5

1
31415926535

Sample Output 5

-1

题意:给出一个数字 n,其在进制 b 下的各位数字的和为 s,现在给出 n 和 s,求 b 是否存在,若存在输出最小值,若不存在,输出 -1

思路:

首先考虑 s 与 n 的关系:

  • s=n 时,最小的 b 是 s+1
  • s>n 时,无解,输出 -1
  • s

设数字 n 的位数为 m,其各位的值为:x_0,x_1,x_2,...,x_m

那么,根据题意,有:\left\{\begin{matrix}x_0+x_1+x_2+...+x_m=s \\ x_0*b^0+x_1*b^1+x_2*b^2+...+x_m*b^m=n \end{matrix}\right.

由于数字位数的特性,那么可以讨论 b 与 n 的关系,假设 n 在 b 进制下最高次幂为 2,那么就有 b^2\leqslant n,即讨论如下两种情况:

  • b\leqslant \sqrt n 时:b 进制的最高次幂为二次幂及以上,暴力枚举
  • b> \sqrt n 时:b 进制的最高次幂为二次幂以下,有:\left\{\begin{matrix}x_0+x_1*b=n \\ x_0+x_1=s \end{matrix}\right.,化简得:b=\frac{n-s}{x_1+1},于是枚举 x1 判断 b 是否合法即可

Source Program

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 50+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;

int main() {
    LL n,s;
    scanf("%lld%lld",&n,&s);
    if(n==s)
        printf("%lld\n",s+1);
    else if(nsqrt(n)
        LL res;
        for(LL i=2; i<=mid; i++) { //枚举b
            res=0;
            LL temp=n;
            while(temp) {
                res+=temp%i;
                temp/=i;
            }
            if(res==s) {
                printf("%lld\n",i);
                flag=true;
                break;
            }
        }

        //b<=sqrt(n)
        if(!flag) {
            LL factor=n-s;
            LL res;
            mid=sqrt(factor)+1;
            for(LL i=mid; i>=1; i--) {//枚举x1
                if(factor%i==0) {
                    res=factor/i+1;
                    LL j=s-i;//x2
                    if(i=2&&j=0) { //判断b的合法性
                        printf("%lld\n",res);
                        flag=true;
                        break;
                    }
                }
            }
        }

        //其他情况
        if(!flag)
            printf("-1\n");
    }

    return 0;
}

 

你可能感兴趣的:(#,AtCoder,数学——其他)