题目:http://poj.org/problem?id=3208

数位DP,首先按位数预处理出每一种位数的情况,包括有多少个魔鬼数和有多少个以6开头的非魔鬼数,以便递推、累加等等;

然后先找出第X个魔鬼数的位数,再一位一位从0开始填数;

写法有些技巧,详见代码及注释。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int t,x,f[][];
void cl()
{
/*
f[i][3]=f[i-1][3]*10+f[i-1][2];
f[i][2]=f[i-1][1];
f[i][1]=f[i-1][0];
f[i][0]=(f[i-1][0]+f[i-1][1]+f[i-1][2])*9;
*/
f[][]=;//!
for(int i=;i<;i++)
{
for(int j=;j<=;j++)
{
f[i+][j+]+=f[i][j];
f[i+][]+=f[i][j]*;
}
f[i+][]+=*f[i][];
}
}
int main()
{
scanf("%d",&t);
cl();
while(t--)
{
scanf("%d",&x);
int m;//!
for(m=;f[m][]<x;m++);//位数 ——实际总比f记录的多
for(int i=m,k=;i>=;i--)//所有魔鬼数数量累计 ,k表示末尾已经有k个6
for(int j=;j<=;j++)
{
long long cnt=f[i-][];
if(j==||k==)//另外加
for(int l=max(,-k-(j==));l<;l++)//l为加上的最小限制
cnt+=f[i-][l];
if(cnt<x)//则第i位应填更大的数;
{
x-=cnt;//j+1,减去上一层的魔鬼数数量
continue;
}
else//本位填j,再缩小范围
{
if(k<&&j==)k++;
if(k<&&j!=)k=;//k=3意为本身已经是魔鬼数,不再改变
printf("%d",j);//第i位填了j
break;
}
}
printf("\n");
}
return ;
}

最新文章

  1. JVM 架构解读
  2. Python数据分析
  3. sshd安装
  4. JS-鼠标经过显示二级菜单
  5. rh6安装oracle11g+ASM
  6. tomcat内存修改 解决内存溢出异常
  7. Hadoop:使用Mrjob框架编写MapReduce
  8. 关于ADO.NET 实体数据数据模型无法为Mysql 选择6.0 解决方案
  9. GitHub使用教程for VS2012
  10. UVA 12563 Jin Ge Jin Qu hao
  11. 在webstrorm中配置好es6 babel
  12. CENTOS6.4安装lxml失败
  13. 【Python系列】Python自动发邮件脚本-html邮件内容
  14. 关于Android中so解析那些事
  15. CentOS6.9升级autoconf版本,解决”Autoconf version 2.64 or higher is required“错误
  16. conda环境复制
  17. Python爬虫目录
  18. XML 和 DTD
  19. python ctypes
  20. IEnumerable 与 IEnumerable&lt;T&gt;

热门文章

  1. HTML5 2D平台游戏开发#3冲刺
  2. js判断参数类型
  3. iOS打包(ipa包)
  4. XMPP协议概述
  5. 【Unity 3D】学习笔记三十:游戏元素——游戏地形
  6. Android-理解window和windowmanager
  7. Java知识点梳理——读写分离
  8. mongodb.py
  9. 用CMakeLists.txt组织工程
  10. Django框架ORM常用参数汇总_模型层