数位和乘积(digit.cpp/c/pas)

【题目描述】

一个数字的数位和乘积为其各位数字的乘积。求所有的N位数中有多少个数的数位和乘积恰好为K。请注意,这里的N位数是可以有前导零的。比如01,02视为二位数,但是他们的数位和乘积都是0。

【输入格式】

一行两个整数N,K

【输出格式】

一个行一个整数表示结果。

【样例输入】

2 3

【样例输出】

2

【样例输入2】

2 0

【样例输出2】

19

【数据范围】

对于20%:N <= 6。

对于50%:N<=16

存在另外30%:K=0。

对于100%:N <= 50,0 <= K <= 10^9。

……这题要分类讨论

1、k==0时,答案是n位数中至少有一个的方案数。根据容斥原理就是总的方案数-n位数中一个0也没有的方案数,即10^n-9^n。因为n<=50,要高精度乘、减

2、k!=0时,先分解质因数。如果有2、3、5、7以外的质因数,肯定无解。因为k是各位乘起来的积,不可能出现有一位是11、13之类

然后保存2、3、5、7的指数(设为m2、m3、m5、m7)

令f[i][j][k][l][m]表示前i位凑出j个2、k个3、l个5、m个7的方案数

然后转移就是枚举第i位是1到9的转移(好麻烦啊不想写在这里了……看我代码)

根据计算因为k<=10e,所以只要开数组f[55][30][20][14][12]就差不多了

这样每个f依然要高精度……MLE啦……所以还要滚动数组或者像一维背包dp的做法一样倒着for就可以省掉第一维

(哇啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊因为我的高精数组清0刚好少算一位就wa了只有90不开心啊啊啊啊啊啊啊啊啊啊)

#include<cstdio>
#include<cstring>
#define mx 50
#define LL long long
struct gaojing{int len;int a[mx+10];
}f[30][20][14][12];
int n,k;
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
inline void set0(gaojing &s)
{s.len=0;for (int i=1;i<mx+5;i++)s.a[i]=0;
}
inline void put(gaojing a)
{for (int i=a.len;i>=1;i--)printf("%d",a.a[i]);printf("\n");
}
inline void addi(gaojing a,gaojing b,gaojing &c)
{set0(c);int maxlen=max(a.len,b.len);  for (int i=1;i<=maxlen;i++)  {  c.a[i]=c.a[i]+a.a[i]+b.a[i];  if (c.a[i]>=10)  {  c.a[i+1]+=c.a[i]/10;c.a[i]%=10;}}  c.len=maxlen+1;  while (!c.a[c.len]&&c.len>1) c.len--;
}
inline void jian(gaojing a,gaojing b,gaojing &c)
{set0(c);for (int i=1;i<=b.len;i++){c.a[i]=a.a[i]-b.a[i];if (c.a[i]<0){c.a[i]+=10;int now=i+1;while (!a.a[now]){a.a[now]=9;now++;}a.a[now]--;}}for (int i=b.len+1;i<=a.len;i++)c.a[i]=a.a[i];c.len=a.len;while (c.a[c.len]==0&&c.len>1)c.len--;
}
inline void mult(gaojing a,gaojing b,gaojing &c)
{set0(c);for(int i=1;i<=a.len;i++)for (int j=1;j<=b.len;j++)c.a[i+j-1]+=a.a[i]*b.a[j];int mxlen=a.len+b.len+3;for (int i=1;i<=mxlen;i++){c.a[i+1]+=c.a[i]/10;c.a[i]%=10;}while (c.a[mxlen]==0)mxlen--;c.len=mxlen;
}
const int prime[5]={0,2,3,5,7};
int num[5];
int main()
{freopen("digit.in","r",stdin);freopen("digit.out","w",stdout);scanf("%d%d",&n,&k);if (k==0)//若k=0,方案数为10^n-9^n {gaojing sum;set0(sum);gaojing tomul;set0(tomul);gaojing decs;set0(decs);sum.len=1;sum.a[1]=1;tomul.len=1;tomul.a[1]=9;decs.len=n+1;decs.a[n+1]=1;for(int i=1;i<=n;i++)mult(sum,tomul,sum);jian(decs,sum,sum);put(sum);return 0;}for (int i=1;i<=4;i++)while (k%prime[i]==0){k/=prime[i];num[i]++;}if (k!=1){printf("0");return 0;}f[0][0][0][0].a[1]=1;f[0][0][0][0].len=1;for (int i=0;i<=num[1];i++)for (int j=0;j<=num[2];j++)for (int k=0;k<=num[3];k++)for (int l=0;l<=num[4];l++)f[i][j][k][l].len=1;for (int i=1;i<=n;i++){int m2=min(num[1],3*i);int m3=min(num[2],2*i);int m5=min(num[3],i);int m7=min(num[4],i);for (int j=m2;j>=0;j--)for (int k=m3;k>=0;k--)for (int l=m5;l>=0;l--)for (int m=m7;m>=0;m--){if (j>=1)addi(f[j][k][l][m],f[j-1][k]  [l]  [m]  ,f[j][k][l][m]);//2if (k>=1)addi(f[j][k][l][m],f[j]  [k-1][l]  [m]  ,f[j][k][l][m]);//3if (j>=2)addi(f[j][k][l][m],f[j-2][k]  [l]  [m]  ,f[j][k][l][m]);//4if (l>=1)addi(f[j][k][l][m],f[j]  [k]  [l-1][m]  ,f[j][k][l][m]);//5if (j&&k)addi(f[j][k][l][m],f[j-1][k-1][l]  [m]  ,f[j][k][l][m]);//6if (m>=1)addi(f[j][k][l][m],f[j]  [k]  [l]  [m-1],f[j][k][l][m]);//7if (j>=3)addi(f[j][k][l][m],f[j-3][k]  [l]  [m]  ,f[j][k][l][m]);//8if (k>=2)addi(f[j][k][l][m],f[j]  [k-2][l]  [m]  ,f[j][k][l][m]);//9}}put(f[num[1]][num[2]][num[3]][num[4]]);
}

  

转载于:https://www.cnblogs.com/zhber/p/4035998.html

2014.9.13模拟赛【数位和乘积】相关推荐

  1. 2014.7.7模拟赛【无线通讯网】

    [题目描述] 国防部计划用无线网络连接若干个边防哨所.2种不同的通讯技术用来搭建无线网络:每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  2. 5.13模拟赛 赛后回顾

    文章目录 1.T1(联) 题目描述: 题目解答: 2.T2(赛) 题目描述: 题目解答: 3.T3(题) 题目描述: 题目解答: 1.T1(联) 题目描述: 题目解答: · 老师的做法: 离散化每个点 ...

  3. 2014.11.12模拟赛【最小公倍数】| vijos1047最小公倍数

    最小公倍数(lcm.c/.cpp/.pas) 题目描述 给定两个正整数,求他们的最小公倍数. 样例输入 28 12 样例输出 84 数据范围 对于40%数据:1<=a,b<=10^9 对于 ...

  4. 2014.11.12模拟赛【美妙的数字】| vijos1904学姐的幸运数字

    美妙的数字(number.c/.cpp/.pas) 题目描述 黄巨大认为非负整数是美妙的,并且它的数值越小就越美妙.当然0是最美妙的啦. 现在他得到一串非负整数,对于每个数都可以选择先对它做二进制非运 ...

  5. 2014.8.15模拟赛【公主的朋友】

    题意是支持两种操作:区间染色:询问区间[l,r]之间有多少个颜色是x的. wulala的题解是这样写的 30分的话直接暴力, 60分对于每种宗教维护一颗线段树 100分的话分块就可以了,每次暴力处理起 ...

  6. 2014.8.15模拟赛【公主的工作】bzoj1046[HAOI2007]上升序列

    bzoj题目是这样的 Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm ...

  7. 纪中集训2020.01.13【NOIP普及组】模拟赛C组总结————My First Time Write Summary

    纪中集训2020.01.13[NOIP普及组]模拟赛C组总结 题目编号 标题 0 [NOIP普及组模拟]取值( numbers.pas/cpp) 1 [NOIP普及组模拟]数对(pairs.pas/c ...

  8. 2021年 第12届 蓝桥杯 第4次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...

  9. 2021年 第12届 蓝桥杯 第3次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...

最新文章

  1. CCF-201612-3 -权限查询
  2. [k8s] 第八章 数据存储
  3. 用神经集认识手写数字
  4. Maven编译jar出现:无法确定 T 的类型参数的异常的原因和处理方案
  5. Mock.js mysql_平台支持mock功能—未完成版
  6. Java代理模式/静态代理/动态代理
  7. 窗口分析函数_10_计算组总和的占比
  8. 微电子学与计算机期刊投稿模板,微电子学与计算机投稿要求
  9. python提供两个对象身份比较操作符_标准类型对象比较操作符
  10. 重磅!TensorFlow 2.0 来了!
  11. linux 程序调试日志,Linux程序调试
  12. 5G NR 标准:下一代无线通信技术
  13. javax.crypto.BadPaddingException: Given final block not properly padded 解决方法
  14. css按钮音效设置,带悬停音效(超低声波)的磁吸按钮
  15. 使用一个虚拟环境,但是运用其他环境中的库!【pycharm】
  16. 最新python中一升级所有已安装的包方法
  17. matlab使用笔记(一)——matlab语言中if、for语句与C语言中的差别
  18. c语言细胞自动机,关于细胞自动机的程序..求救!!谢谢!
  19. 教你一招:Win10系统如何正确卸载edge浏览器?
  20. 命令行查询ip所在地——Nali

热门文章

  1. Centos中查找文件、目录、内容
  2. NOIP2007 count 统计数字
  3. cocos2dX 之数据存储
  4. MySQL多项模糊查询
  5. C++ 中关于optional 使用过程中遇到的问题
  6. kendo-ui学习笔记——题记
  7. php 非常有用的高级函数PATH_SEPARATOR常量和set_include_path
  8. PHP企业级开发环境配置全攻略-IDE+SVN++(转)
  9. 重新设定mysql密码~,网上方法都是,这里选一个。
  10. android系统的发展态势,2020年安卓手机发展的7个趋势,只有延伸,并无革命性的变化...