URAL 1057 Amount of Degrees (数位DP,入门)
题意:
求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的,B的整数次幂之和。例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足了要求: 17 = 24+20, 18 = 24+21, 20 = 24+22。(以B为底数,幂次数不允许相同)
参考论文--》》论文中的题。
思路:
论文倒是容易看明白,但是这个转成B进制的思想一直转不过来。其实转成B进制后变成 a1*Bn+a2*Bn-1...an*B0。其中ai是系数。范围是[0,B-1]。但是看了论文知道,里面画的那棵01树(树上的01就是代表系数a),只有从根走到叶子,经过的1的个数为K才是满足要求的。那么如果a大于0怎么办?那么从树上该点开始的整棵子树就可以全部进行考虑了。而如果刚好考虑的位为1的呢?那么取该位为0的那棵子树就行了。
两种实现
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
using namespace std;
const double PI = acos(-1.0);
const int N=; //注意大小 int f[N][N]; void pre_cal() //预处理组合数
{
f[][]=;
for(int i=; i<N; i++) //位数
{
f[i][]=f[i][i]=;
for(int j=; j<i; j++) //多少个1
{
f[i][j]=f[i-][j]+f[i-][j-];
}
}
} int bit[N];
int cal(int n,int k,int b)
{
memset(bit, , sizeof(bit));
int len=, cnt=, ans=;
while(n) //转成b进制
{
bit[++len]=n%b;
n/=b;
}
for(int i=len; i>; i--)
{
if(bit[i]>)
{
ans+=f[i][k-cnt]; //取整棵子树
break;
}
else if( bit[i]== )
{
ans+=f[i-][k-cnt]; //统计左边的
if(++cnt>k) break; //已超
}
}
if(cnt==k) ans++;
return ans;
} int main()
{
//freopen("input.txt","r",stdin);
pre_cal();
int x, y, k, b;
while(~scanf("%d%d%d%d",&x,&y,&k,&b))
printf("%d\n", cal(y,k,b)-cal(x-,k,b));
return ;
}
AC代码
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
using namespace std;
const double PI = acos(-1.0);
const int N=; int f[N][N];
void pre_cal() //预处理组合数
{
f[][]=;
for(int i=; i<N; i++) //位数
{
f[i][]=f[i][i]=;
for(int j=; j<i; j++) //多少个1
{
f[i][j]=f[i-][j]+f[i-][j-];
}
}
}
int bit[N];
int cal(int n,int k,int b)
{
memset(bit, , sizeof(bit));
int len=, cnt=, ans=, flag=;
while(n) //转成b进制
{
bit[++len]=n%b;
n/=b;
if(bit[len]>) flag=;
} if(flag==)
{
//找到第一位大于1的,改为1,然后后面可以全部改成1了
for(int i=len; i>; i--)
if(bit[i]>)
{
for(int j=i; j>; j--) bit[j]=;
break;
}
} for(int i=len; i>; i--)
{
if( bit[i] )
{
ans+=f[i-][k-cnt]; //统计左边的
if(++cnt>k) break; //已超
}
}
if(cnt==k) ans++;
return ans;
} int main()
{
//freopen("input.txt","r",stdin);
pre_cal();
int x, y, k, b;
while(~scanf("%d%d%d%d",&x,&y,&k,&b))
printf("%d\n", cal(y,k,b)-cal(x-,k,b));
return ;
}
AC代码
URAL 1057 Amount of Degrees (数位DP,入门)的更多相关文章
- URAL 1057. Amount of Degrees(数位DP)
题目链接 我看错题了...都是泪啊,不存在3*4^2这种情况...系数必须为1... #include <cstdio> #include <cstring> #include ...
- [ACM] ural 1057 Amount of degrees (数位统计)
1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the am ...
- Ural 1057 Amount of Degrees
Description 问[L,R]中有多少能表示k个b次幂之和. Sol 数位DP. 当2进制时. 建出一个二叉树, \(f[i][j]\) 表示长度为 \(i\) 有 \(j\) 个1的个数. 递 ...
- Ural1057 - Amount of Degrees(数位DP)
题目大意 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和.例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意: 输入:第一行包含两个整 ...
- URAL 1057 Amount of Degrees (数位dp)
Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactly ...
- ural 1057 Amount of degrees 【数位dp】
题意:求(x--y)区间转化为 c 进制 1 的个数为 k 的数的出现次数. 分析:发现其满足区间减法,所以能够求直接求0---x 的转化为 c 进制中 1 的个数为k的数的出现次数. 首先用一个数组 ...
- [ural1057][Amount of Degrees] (数位dp+进制模型)
Discription Create a code to determine the amount of integers, lying in the set [X; Y] and being a s ...
- Timus Online Judge 1057. Amount of Degrees(数位dp)
1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the am ...
- xbz分组题B 吉利数字 数位dp入门
B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...
随机推荐
- mysql Split函数
mysql没有split函数,这里手动写一个: ),)) BEGIN CREATE TEMPORARY TABLE IF NOT EXISTS temp_split ( col ) ); DELETE ...
- 实训随笔4:HTML初入门
1.<td>与<tr>标签 表格制作时,应该一行一行的画,即<tr>应该包含<td>标签,正确示例如下: <h3>测试数组初始化与操作< ...
- C# 获取外网IP和运营商和城市
/// <summary> /// 获取客户端外网IP,省份,城市,运营商 /// 2012年12月18日 15:07 /// </summary> public class ...
- AI资源
网易云课堂 http://study.163.com/topics/IBMOfflinePrograms?utm_source=baidu&utm_medium=cpc&utm_cam ...
- 51nod1065(set.upper_bound()/sort)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1065 题意:中文题诶- 思路: 解法1:set容器,将所有前 ...
- GHOST操作
通过详细的图文说明,怎么用ghost备份系统,以备系统中毒或者感觉不好用时,快速恢复到备份时的状态! 工具/原料 2013最新雨林木风ghostxpxp3系统或者老毛桃等工具 方法/步骤 1 重新启动 ...
- 18.使用for循环计算+1-3+5-7+9-11+13...99的结果
j = 1 # -1 num1 = 0 #1-3 for i in range(1,100,2): num1 += j * i # -3 j = j * -1 # 1 print(num1) sum1 ...
- 深入理解JVM的类加载
前言: 前面又说到Java程序实际上是将.class文件放入JVM中运行.虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换,解析和初始化,最终形成可以被虚拟机直接使用的Java类 ...
- oracle view and MATERIALIZED VIEW
View http://blog.csdn.net/tianlesoftware/article/details/5530618 MATERIALIZED VIEW http://blog.csdn. ...
- C# 操作 Excel 文件(.xls 或 .xlsx)
在.net中,常用的操作excel文件的方式,有三种: OLE DB的形式, 第三方框架NPOI, Office组件. 总结: 通过对比,在读取大数据量的excel文件,建议用OLE DB的形式,把e ...