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