ural1057 Amount of degrees
Description
求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和。例如,
设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:
17 = 24+20,
18 = 24+21,
20 = 24+22。
数据规模:1≤X≤Y≤2^31-1,1≤K≤20, 2≤B≤10
Sample Input
1345 2004954181 1 5
Sample Output
9
数位dp。
#include<bits/stdc++.h>
#define ll long long
#define pps 50
using namespace std;
ll x,y,k,b;
ll a[pps],f[pps][pps];//i位有j个1的情况
void init(){
scanf("%d%d%d%d",&x,&y,&k,&b);
f[0][0]=1;// 0位0个1为 1
for(int i=1;i<=32;i++)
{
f[i][0]=1;
for(int j=1;j<=i;j++)
{
f[i][j]=f[i-1][j]+f[i-1][j-1];
//f[i-1][j] i-1位有j个1 当前位为0
//f[i-1][j-1] i-1位有j-1个1 当前位为1
}
}
}
int work(int N){
int ans=0,len=0,n=N,need_1=k;
while(n)
{
a[++len]=n%b;
n/=b;//转B进制数
}
for(int i=len;i>=1;i--)
{
if(a[i]==1)
ans+=f[i-1][need_1],need_1--;//找到一个1,need--
//因为严格小于num,所以强制a[i]=0,之后所有位都为1,ans+=i-1位j个1的情况
else if(a[i]>1){
ans+=f[i][need_1];//因为严格小于num,所以强制a[i]=1,之后所有位都为1,ans+=i位j个1的情况
break;
}
if(need_1<0)return ans;//不需要1,return;
}
//如果num本身也是ans++
if(need_1==0)ans++;
return ans;
}
int main(){
init();
printf("%d\n",work(y)-work(x-1));
return 0;
}