题意:

  求给定区间[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的那棵子树就行了。

  两种实现

  1. //#include <bits/stdc++.h>
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <map>
  7. #include <algorithm>
  8. #include <vector>
  9. #include <iostream>
  10. #define pii pair<int,int>
  11. #define INF 0x7f3f3f3f
  12. #define LL long long
  13. using namespace std;
  14. const double PI = acos(-1.0);
  15. const int N=; //注意大小
  16.  
  17. int f[N][N];
  18.  
  19. void pre_cal() //预处理组合数
  20. {
  21. f[][]=;
  22. for(int i=; i<N; i++) //位数
  23. {
  24. f[i][]=f[i][i]=;
  25. for(int j=; j<i; j++) //多少个1
  26. {
  27. f[i][j]=f[i-][j]+f[i-][j-];
  28. }
  29. }
  30. }
  31.  
  32. int bit[N];
  33. int cal(int n,int k,int b)
  34. {
  35. memset(bit, , sizeof(bit));
  36. int len=, cnt=, ans=;
  37. while(n) //转成b进制
  38. {
  39. bit[++len]=n%b;
  40. n/=b;
  41. }
  42. for(int i=len; i>; i--)
  43. {
  44. if(bit[i]>)
  45. {
  46. ans+=f[i][k-cnt]; //取整棵子树
  47. break;
  48. }
  49. else if( bit[i]== )
  50. {
  51. ans+=f[i-][k-cnt]; //统计左边的
  52. if(++cnt>k) break; //已超
  53. }
  54. }
  55. if(cnt==k) ans++;
  56. return ans;
  57. }
  58.  
  59. int main()
  60. {
  61. //freopen("input.txt","r",stdin);
  62. pre_cal();
  63. int x, y, k, b;
  64. while(~scanf("%d%d%d%d",&x,&y,&k,&b))
  65. printf("%d\n", cal(y,k,b)-cal(x-,k,b));
  66. return ;
  67. }

AC代码

  1. //#include <bits/stdc++.h>
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <cmath>
  6. #include <map>
  7. #include <algorithm>
  8. #include <vector>
  9. #include <iostream>
  10. #define pii pair<int,int>
  11. #define INF 0x7f3f3f3f
  12. #define LL long long
  13. using namespace std;
  14. const double PI = acos(-1.0);
  15. const int N=;
  16.  
  17. int f[N][N];
  18. void pre_cal() //预处理组合数
  19. {
  20. f[][]=;
  21. for(int i=; i<N; i++) //位数
  22. {
  23. f[i][]=f[i][i]=;
  24. for(int j=; j<i; j++) //多少个1
  25. {
  26. f[i][j]=f[i-][j]+f[i-][j-];
  27. }
  28. }
  29. }
  30. int bit[N];
  31. int cal(int n,int k,int b)
  32. {
  33. memset(bit, , sizeof(bit));
  34. int len=, cnt=, ans=, flag=;
  35. while(n) //转成b进制
  36. {
  37. bit[++len]=n%b;
  38. n/=b;
  39. if(bit[len]>) flag=;
  40. }
  41.  
  42. if(flag==)
  43. {
  44. //找到第一位大于1的,改为1,然后后面可以全部改成1了
  45. for(int i=len; i>; i--)
  46. if(bit[i]>)
  47. {
  48. for(int j=i; j>; j--) bit[j]=;
  49. break;
  50. }
  51. }
  52.  
  53. for(int i=len; i>; i--)
  54. {
  55. if( bit[i] )
  56. {
  57. ans+=f[i-][k-cnt]; //统计左边的
  58. if(++cnt>k) break; //已超
  59. }
  60. }
  61. if(cnt==k) ans++;
  62. return ans;
  63. }
  64.  
  65. int main()
  66. {
  67. //freopen("input.txt","r",stdin);
  68. pre_cal();
  69. int x, y, k, b;
  70. while(~scanf("%d%d%d%d",&x,&y,&k,&b))
  71. printf("%d\n", cal(y,k,b)-cal(x-,k,b));
  72. return ;
  73. }

AC代码

URAL 1057 Amount of Degrees (数位DP,入门)的更多相关文章

  1. URAL 1057. Amount of Degrees(数位DP)

    题目链接 我看错题了...都是泪啊,不存在3*4^2这种情况...系数必须为1... #include <cstdio> #include <cstring> #include ...

  2. [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 ...

  3. Ural 1057 Amount of Degrees

    Description 问[L,R]中有多少能表示k个b次幂之和. Sol 数位DP. 当2进制时. 建出一个二叉树, \(f[i][j]\) 表示长度为 \(i\) 有 \(j\) 个1的个数. 递 ...

  4. Ural1057 - Amount of Degrees(数位DP)

    题目大意 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和.例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意: 输入:第一行包含两个整 ...

  5. 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 ...

  6. ural 1057 Amount of degrees 【数位dp】

    题意:求(x--y)区间转化为 c 进制 1 的个数为 k 的数的出现次数. 分析:发现其满足区间减法,所以能够求直接求0---x 的转化为 c 进制中 1 的个数为k的数的出现次数. 首先用一个数组 ...

  7. [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 ...

  8. 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 ...

  9. xbz分组题B 吉利数字 数位dp入门

    B吉利数字时限:1s [题目描述]算卦大湿biboyouyun最近得出一个神奇的结论,如果一个数字,它的各个数位相加能够被10整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...

随机推荐

  1. Codeforces 489A SwapSort (水题)

    A. SwapSort time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  2. web前端之Html和Css应用中的细节问题

    1.居中的n种方法:①.margin: 0 20%; ——设置margin上下外边距的值设置为0,左右外边距设置成相同的百分比,既可将盒子居中. ②.margin: 0 auto;width: 100 ...

  3. AI决策算法 之 GOAP (一)

    http://blog.csdn.net/lovethrain/article/details/67632033 本系列文章内容部分参考自:http://gamerboom.com/archives/ ...

  4. ue4 杂记

    c++获取GameMode if(GetWorld()) { auto gamemode = (ASomeGameMode*)GetWorld()->GetAuthGameMode(); } 或 ...

  5. 分层确定性钱包开发的代码实现(HD钱包服务)

    HD Wallets的全称是Hierachical Deterministic Wallets, 对应中文是 分层确定性钱包. 这种钱包能够使用一组助记词来管理所有的账户的所有币种,在比特币的BIP3 ...

  6. mac搭建TensorFlow环境

    1.首先安装Anaconda,下载地址:https://www.anaconda.com/download/#macos,根据需要下载所需的版本. 2.安装TensorFlow,安装命令:pip in ...

  7. vuex初使用(写的当然是最简单的应用啦)

    关于vuex的简图 vuex文档:https://vuex.vuejs.org/zh-cn/installation.html 一:npm安装 npm install vuex --save 在mai ...

  8. String常用方法简介

    1. 创建String对象的常用方法 (1) String s1 = "mpptest" (2)  String s2 = new String(); (3) String s3 ...

  9. A Simple Math Problem (矩阵快速幂)

    Lele now is thinking about a simple function f(x).  If x < 10 f(x) = x.  If x >= 10 f(x) = a0 ...

  10. [洛谷P4315] 月下”毛景“树

    题目链接: 点我 题目分析: 树剖.将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题 注意链计算时 ...