Create a code to determine the amount of integers, lying in the set [ X; Y] and being a sum of exactly K 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 = 2 4+2 0,
18 = 2 4+2 1,
20 = 2 4+2 2.
Input
The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 2 31−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 betweenX and Y, being a sum of exactly K different integer degrees of B.
Example
input | output |
---|---|
15 20 2 2 |
3 |
题目大意:给定区间【x,y】中满足区间中的数正好满足是由k个互不相等的B的整数次幂之和,求出有几个这样子的数
思路:http://wenku.baidu.com/view/d2414ffe04a1b0717fd5dda8.html
观察一下上面的网页吧,很仔细了
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int x,y,k,b;
int c[33][33];
void Init() //其实就是组合数
{
c[0][0]=1;
for(int i=1; i<=31; i++)
{
c[i][0]=c[i-1][0];
for(int j=1; j<=i; j++)
c[i][j]=c[i-1][j]+c[i-1][j-1];
}
}
int change(int n) //转换进制问题了
{
int w[33];
int len=0;
while(n)
{
w[len++]=n%b;
n/=b;
}
int ans=0;
for(int i=len-1; i>=0; i--)
if(w[i]>1)
{
for(int j=i;j>=0;j--)
ans+=(1<<j);
break;
}
else
ans+=(w[i]<<i);
return ans;
}
int calc(int x,int k)
{
int tot=0,ans=0;
for(int i=31;i>=0;i--)
{
if(x&(1<<i))
{
tot++;
if(tot>k) break;
x=x^(1<<i);
}
if(1<<(i-1)<=x)
ans+=c[i-1][k-tot]; //第i位为1(从0开始的),那么后面还剩下i个数字,后面的第一个数字为0,
//从i-1个数字中任意挑k-tot个
}
if(tot+x==k)
ans++;
return ans;
}
int main()
{
Init();
cin>>x>>y>>k>>b;
cout<<calc(change(y),k)-calc(change(x-1),k)<<endl;
return 0;
}