1057. Amount of Degrees
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK different integer degrees of B.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 24+20,
18 = 24+21,
20 = 24+22.
18 = 24+21,
20 = 24+22.
Input
The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 231−1).
The next two lines contain integers K and B (1 ≤ K ≤ 20; 2 ≤ B ≤ 10).
Output
Output should contain a single integer — the amount of integers, lying between X and Y, being a sum of exactly K different integer degrees of B.
Sample
input | output |
---|---|
15 20 2 2 |
3 |
Problem Source: Rybinsk State Avia Academy
Tags: none
)题意:
首先定义了一种数为特殊数。
特殊数仅仅邮k个不同的b^x组成。
如今问你[x,y]里有多少这种特殊数。
思路:
数位DP。
dp[i][j]表示二进制表示中。前i为1的个数为j一共同拥有多少个数。其他进制类似处理。注意边界。
具体见代码:
#include<algorithm> #include<iostream> #include<string.h> #include<stdio.h> #include<stdlib.h> using namespace std; const int INF=0x3f3f3f3f; const int maxn=100010; typedef long long ll; int dp[35][35],base[35],bin[35]; void init() { dp[0][0]=base[0]=1; for(int i=1;i<=32;i++) { dp[i][0]=1; base[i]=base[i-1]<<1; for(int j=1;j<=i;j++) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]; } } int calc(int x,int k) { int i,one=0,ans=0; for(i=31;i>=0;i--) { if(x&base[i]) { if(one>k) break; ans+=dp[i][k-one]; one++; x-=base[i]; } } if(one==k) ans++; return ans; } int getbin(int x,int b) { int ct=0,i,ret=0; if(!x) return x; while(x) { bin[ct++]=x%b; x/=b; } for(i=ct-1;i>=0;i--) { if(bin[i]>1) break; if(bin[i]) ret=ret<<1|1; else ret<<=1; } while(i>=0) { ret=ret<<1|1; i--; } return ret; } int main() { int x,y,k,b; init(); while(~scanf("%d%d%d%d",&x,&y,&k,&b)) { y=getbin(y,b); x=getbin(x-1,b); printf("%d ",calc(y,k)-calc(x,k)); } return 0; }