ural1057 Amount of degrees

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值