Amount of Degrees 度的数量

自己的写法

// Amount of Degrees 度的数量.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*
* https://loj.ac/p/10163
* http://ybt.ssoier.cn:8088/problem_show.php?pid=1585
*
题目描述
原题来自:NEERC 2000 Central Subregional,题面详见 Ural 1057。

求给定区间 [X,Y] 中满足下列条件的整数个数:这个数恰好等于 K 个互不相等的 B 的整数次幂之和。
例如,设 X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:
17 = 2^4+2^0
18 = 2^4 + 2^1
20 = 2^4+2^2



输入格式
第一行包含两个整数 X 和 Y,接下来两行包含整数 K 和 B。

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

样例
输入
15 20
2
2
输出
3


对于全部数据,1<= X<= Y<= 2^31 - 1,1<= K<= 20,2<= B<= 10。
*/


#include <iostream>
#include <vector>
#include <cstring>


using namespace std;

int dp[35][35][2];
int K, B;

int dfs(const vector<int>& v, int len, int k, int limit) {
    int& ret = dp[len][k][limit];
    if (len == 0) {
        if (limit == 1) {
            if (v[len] >= 1)
                return k == 0 || k == 1;
            else if (v[len] == 0)
                return k == 0;
        }
        else {
            return  k == 0 || k == 1;
        }
    }

    if (ret != -1)
        return ret;

    ret = 0;

    if (limit == 0 || v[len] > 1) {
        ret += dfs(v, len - 1, k, 0);
        ret += dfs(v, len - 1, k - 1, 0);
    }
    else if (limit == 1) {
        if (v[len] == 0)
            ret += dfs(v, len - 1, k, 1);
        else if (v[len] == 1) {
            ret += dfs(v, len - 1, k, 0);
            ret += dfs(v, len - 1, k - 1, 1);
        }
    }

    return ret;
}



int calc(int n) {
    vector<int> v;
    memset(dp, -1, sizeof dp);

    while (n != 0) {
        v.push_back(n % B);
        n = n / B;
    }

    int ret = dfs(v, v.size() - 1, K, 1);
    return ret;
}



int main() {
    int x, y;
    cin >> x >> y >> K >> B;

    cout << calc(y) - calc(x - 1) << endl;


    return 0;
}

posted on 2024-07-12 15:01  itdef  阅读(1)  评论(0编辑  收藏  举报

导航