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;
}

浙公网安备 33010602011771号