LOJ #10163. 「一本通 5.3 例 1」Amount of Degrees

描述


求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和。

例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:

17 = 24+20,

18 = 24+21,

20 = 24+22。

输入


第一行包含两个整数X和Y。接下来两行包含整数K和B。

输出


只包含一个整数,表示满足条件的数的个数。

样例输入


15 20
2
2


样例输出


3


数据规模:


1 ≤ X ≤ Y ≤ 2^31−1,1 ≤ K ≤ 20, 2 ≤ B ≤ 10

思路:


其实就是进制拆分啦!!

注意 互不相同: 每一位都是0或1 相当于二进制了。。

 

代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 50;

int h[N];
int f[N][N];
int k, x, y, b;

int solve(int x) {
    int top = -1;
    while (x) {
        int p = x % b;
        x /= b;
        h[++top] = p;
    }
    int tot = 0, ans = 0;
    for (int i = top; i >= 0; --i) {
        if (h[i] == 1) {
            ++tot;
            if (tot > k + 1)
                break;
            if (i > 0)
                ans += f[i - 1][k - tot + 1];
        } else if (h[i] > 1) {
            ans += f[i][k - tot];
            return ans;
        }
    }
    if (tot == k)
        ++ans;
    return ans;
}

int main() {
    scanf("%d%d%d%d", &x, &y, &k, &b);
    f[0][0] = 1;
    f[0][1] = 1;
    for (int i = 1; i <= 31; i++) {
        f[i][0] = 1;
        for (int j = 1; j <= i + 1; j++) f[i][j] = f[i - 1][j - 1] + f[i - 1][j];
    }
    --x;
    int ans = solve(y) - solve(x);
    printf("%d\n", ans);
    return 0;
}

 

posted @ 2019-07-25 21:37  双子最可爱啦  阅读(312)  评论(0编辑  收藏  举报