Description

一个数x各个数位上的数之积记为\(f(x)\)
求[L,R)中满足\(0<f(x)<=n\)的数的个数

solution

最后\(f(x)\)可以拆分成2,3,5,7的乘积,我们就将 \(2,3,5,7\) 压进状态,然后就是基础的数位DP,分是否严格小于两种状态转移即可
具体实现需要一些技巧:
预处理出每一个数含有 \(2,3,5,7\)的个数
预处理出 \(2,3,5,7\) 的幂,方便剪枝
注意数字不能含有 \(0\),我们每DP一位,要新加入 \([1,9]\) 的状态,即前导零的情况

还有一种解法是用 \(map\) 压乘积,网上大部分都是这么做的,也能通过,且简洁很多
tips:代码实现比较简单,但我已不想再多看一眼我的代码....

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=36;
typedef long long ll;
int m,lim[6],pri[6]={0,2,3,5,7};ll f[21][2][33][21][15][13];
char S[22];
ll m5[N],m2[N],m7[N],m3[N];int v[15][6];
ll solve(int *a,int n){if(n==1){int ret=0;for(int i=1;i<a[1];i++)ret+=(i<=m);return ret;}ll x,mu;memset(f,0,sizeof(f));for(int i=1;i<n;i++){if(i==1)for(int j=1;j<=a[i];j++)f[i][j<a[i]][v[j][1]][v[j][2]][v[j][3]][v[j][4]]++;else for(int j=1;j<=9;j++)f[i][1][v[j][1]][v[j][2]][v[j][3]][v[j][4]]++;for(int j=0;j<=lim[1];j++){if(m2[j]<=m)for(int k=0;k<=lim[2];k++){if(m2[j]*m3[k]<=m)for(int g=0;g<=lim[3];g++){if(m2[j]*m3[k]*m5[g]<=m)for(int b=0;b<=lim[4];b++){mu=m2[j]*m3[k]*m5[g]*m7[b];if(mu>m)break;x=f[i][1][j][k][g][b];if(x)for(int d=1;d<=9 && mu*d<=m;d++)f[i+1][1][j+v[d][1]][k+v[d][2]][g+v[d][3]][b+v[d][4]]+=x;x=f[i][0][j][k][g][b];if(!x)continue;for(int d=1;d<=a[i+1] && mu*d<=m;d++)
f[i+1][d<a[i+1]][j+v[d][1]][k+v[d][2]][g+v[d][3]][b+v[d][4]]+=x;}}}}}for(int i=n;i<=n;i++)for(int j=1;j<=9;j++)f[i][1][v[j][1]][v[j][2]][v[j][3]][v[j][4]]++;ll ret=0;for(int j=0;j<=lim[1];j++)if(m2[j]<=m)for(int k=0;k<=lim[2];k++)if(m3[k]*m2[j]<=m)for(int g=0;g<=lim[3];g++)if(m2[j]*m3[k]*m5[g]<=m)for(int b=0;b<=lim[4];b++){if(m2[j]*m3[k]*m5[g]*m7[b]>m)break;ret+=f[n][1][j][k][g][b];}return ret;
}
int s1[22],s2[22],l1,l2;
void work()
{scanf("%d",&m);for(int i=1;i<=4;i++)lim[i]=log(m+1)/log(pri[i]);m2[0]=1;for(int i=1;i<=lim[1];i++)m2[i]=m2[i-1]<<1;m3[0]=1;for(int i=1;i<=lim[2];i++)m3[i]=m3[i-1]*3;m5[0]=1;for(int i=1;i<=lim[3];i++)m5[i]=m5[i-1]*5;m7[0]=1;for(int i=1;i<=lim[4];i++)m7[i]=m7[i-1]*7;v[2][1]=1;v[3][2]=1;v[4][1]=2;v[6][1]=1;v[6][2]=1;v[5][3]=1;v[7][4]=1;v[8][1]=3;v[9][2]=2;scanf("%s",S+1);l1=strlen(S+1);for(int i=1;i<=l1;i++)s1[i]=S[i]-'0';scanf("%s",S+1);l2=strlen(S+1);for(int i=1;i<=l2;i++)s2[i]=S[i]-'0';ll ans=solve(s2,l2)-solve(s1,l1);printf("%lld\n",ans);
}int main()
{freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);work();return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/7683249.html

bzoj 3679: 数字之积相关推荐

  1. 计算并输出正整数n的各位数字之积

    计算并输出正整数n的各位数字之积(如:n=234时,输出234=2*3*4=24). 输入一个正整数n 1 <= n <= 109 输出正整数n的各位数字之积 样例输入 234 样例输出 ...

  2. C语言计算一个整数各位上的数字之积

    计算正整数num的各位上的数字之积. 例如: 输入:2583 经过--(2x5x8x3) 输出:240 输入:102 经过--(1x0x2) 输出:0 输入:136 经过--(1x3x6) `输出:1 ...

  3. C语言计算数字乘积根,c语言,求任意一个整数各位数字之积

    点击查看c语言,求任意一个整数各位数字之积具体信息 答:求整数各位和,将整数各个位分离出来的方法(除10取模)很常用. 函数如下 int intsum(int n) { int sum = 0; wh ...

  4. 求出200到300之间的数,且满足条件:它们三个数字之积为42,三个数字之和为12

    目录 编程练习 任务 编程练习 编写一个程序,求出200到300之间的数,且满足条件:它们三个数字之积为42,三个数字之和为12. 任务 1.循环遍历200到300之间的整数 2.分别取出个位.十位和 ...

  5. 编写一个程序,求出200到300之间的数,且满足条件:它们三个数字之积为42,三个数字之和为12。

    package com.Demo;public class test12 {public static void main(String[] args) {/** 编写一个程序,求出200到300之间 ...

  6. 编写一个程序,求出200到300之间的数,且满足条件:它们三个数字之积为42,三个数字之和为12...

    //定义变量ge.shi.bai,用于存放个位.十位.百位上的数字int number=0;//使用for循环for(number=200;number<300;number++){//取出百位 ...

  7. 每日一小练(「各位数字之积」与「各位数字之和」的差)

    题目描述:输入一个整数 n,请计算并返回该整数「各位数字之积」与「各位数字之和」的差 例如: 输入:234 返回:15 解释:各位数之积 = 2 * 3 * 4 = 24 各位数之和 = 2 + 3 ...

  8. BZOJ 1049 数字序列(LIS)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1049 题意:给出一个数列A,要求:(1)修改最少的数字使得数列严格递增:(2)在( ...

  9. 数字之积 (数位dp)

    一个数x各个数位上的数之积记为f(x) <不含前导零> 求[L,R)中满足0<f(x)<=n的数的个数 Input 第一行一个数n 第二行两个数L.R Output 一个数,即 ...

最新文章

  1. UIScrollView offset in UINavigationController
  2. datagrid出现相同两组数据_stata 数据操作基础知识:以一篇论文数据操作为例
  3. OS / Linux / SIGKILL 和 SIGTERM、SIGINT
  4. android Collections.addAll()的使用
  5. android加载so文件失败,Android无法加载'.so.1'文件
  6. 推荐35个优秀的电子商务网站界面 (转)
  7. Windows下Subversion配置管理员指南
  8. 数据库设计规范 zhuan
  9. 回归分析什么时候取对数_为什么相关或回归分析时 x和y取log
  10. 10个成语理解项目管理的价值观和方法论
  11. 北斗/GNSS在ROS机器人系统的应用
  12. 梯田油菜花海距杭州仅120公里
  13. 测试用例 --- 注册163邮箱密码
  14. 交互设计师成长指引-从平凡到卓越
  15. rx.xxx 和 io.reactivex.xxx RxJava1 和 RxJava2 和 RxJava3
  16. android 视频裁剪view拖动,android – 视频使用特定坐标裁剪或缩放?
  17. 谷歌推出新优化器Lion:优化算法的符号发现
  18. 安装cuda11.1
  19. python均匀分布
  20. 论网站按钮的设计艺术与生命周期

热门文章

  1. java 中JFinal getModel方法和数据库使用出现问题解决办法
  2. PhpExcel数组输出到Excel浏览器下载
  3. ios页面间传递参数四种方式
  4. 【Android 初学】3、控件布局初步
  5. 使用VS2008在windows平台上试用Kinect
  6. HBase数据读取流程解析
  7. DNS IP DOMAIN 详解
  8. (80)FPGA面试题-请画出序列“1101 “检测状态转移图
  9. (14)Verilog HDL参数:parameter
  10. (12)FPGA面试技能提升篇(IUS、PT、Leda)