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整除,则称它为吉利数.现在叫你计算某个区间内有多少个吉利数字. [输入]第 ...
随机推荐
- 慕课网java就业班级
家里电脑教程路径: F:\教程\java-慕课 开发工具路径: D:\java 公司电脑:开发工具路径 J:\java\开发工具 教程路径: G:\学习中\廖雪峰的java教程\1-Java快速入门\ ...
- gideros-with-zerobrane
http://www.indiedb.com/tutorials/gideros-with-zerobrane
- POJ 1845-Sumdiv(快速幂取模+整数唯一分解定理+约数和公式+同余模公式)
Sumdiv Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u Submit Statu ...
- HTML5学习笔记(三)新属性、功能
HTML5 拖放 1.元素的 draggable 属性设置为 true 2.ondragstart 属性调用函数,函数中dataTransfer.setData() 方法设置被拖数据的数据类型和值 3 ...
- java接口中成员变量和方法的默认修饰符(转)
Java的interface中,成员变量的默认修饰符为:public static final 所以我们在interface中定义成员变量的时候,可以 1:public static final St ...
- vue路由守卫
路由守卫 //路由进来之时 beforeRouteEnter(to, from, next) { console.log(this, 'beforeRouteEnter'); // undefined ...
- 00 | Two Sum
Question Given an array of integers, return indices of the two numbers such that they add up to a sp ...
- React中的代码分割
代码分割想要解决的问题是:经打包工具
- node.js安装与配置
node.js是一个基于Chrome V8引擎的javascrit运行环境. node.js使用了一个事件驱动.非阻塞式I/O的模型,使其轻量又高级. node.js的包管理器npm,是全球最大的开源 ...
- css各种水平垂直居中
css各种水平垂直居中,网上查了一下,总结以下几种 line-height垂直居中 缺点,仅限于单行文字 .item{ text-align: center; height: 100px; line- ...