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整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...
随机推荐
- Codeforces 489A SwapSort (水题)
A. SwapSort time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...
- web前端之Html和Css应用中的细节问题
1.居中的n种方法:①.margin: 0 20%; ——设置margin上下外边距的值设置为0,左右外边距设置成相同的百分比,既可将盒子居中. ②.margin: 0 auto;width: 100 ...
- AI决策算法 之 GOAP (一)
http://blog.csdn.net/lovethrain/article/details/67632033 本系列文章内容部分参考自:http://gamerboom.com/archives/ ...
- ue4 杂记
c++获取GameMode if(GetWorld()) { auto gamemode = (ASomeGameMode*)GetWorld()->GetAuthGameMode(); } 或 ...
- 分层确定性钱包开发的代码实现(HD钱包服务)
HD Wallets的全称是Hierachical Deterministic Wallets, 对应中文是 分层确定性钱包. 这种钱包能够使用一组助记词来管理所有的账户的所有币种,在比特币的BIP3 ...
- mac搭建TensorFlow环境
1.首先安装Anaconda,下载地址:https://www.anaconda.com/download/#macos,根据需要下载所需的版本. 2.安装TensorFlow,安装命令:pip in ...
- vuex初使用(写的当然是最简单的应用啦)
关于vuex的简图 vuex文档:https://vuex.vuejs.org/zh-cn/installation.html 一:npm安装 npm install vuex --save 在mai ...
- String常用方法简介
1. 创建String对象的常用方法 (1) String s1 = "mpptest" (2) String s2 = new String(); (3) String s3 ...
- 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 ...
- [洛谷P4315] 月下”毛景“树
题目链接: 点我 题目分析: 树剖.将边权下放到下方点上(为什么要选深度更深的点?一个父亲可能对应多个儿子,但一个儿子只有一个父亲,即可以保证每个点只保存一条边权)成为经典点权+树剖裸题 注意链计算时 ...