只要某数字的十进制表示中有三个6相邻,则该数字为魔鬼数,求第X小的魔鬼数\(X\le 5e7\)

这一类题目可以先用DP进行预处理,再基于拼凑思想,用“试填法"求出最终的答案

\(F[i,3]\)表示由 \(i\) 位数字构成的魔鬼数有多少个,\(F[i,j](0\le j\le 2)\) 表示由 \(i\) 位数字构成的,开头已经有连续 \(j\) 个6的非魔鬼数有多少个。(允许前导0的存在,想一想为什么)

转移方程

  1. \(F[i,0] = 9*(F[i-1,0] + F[i-1,1] + F[i-1,2])\)
  2. \(F[i,1] = F[i-1,0]\)
  3. \(F[i,2] = F[i-1,1]\)
  4. \(F[i,3] = F[i-1,2] + 10 * F[i-1,3]\)

然后一位一位的试填,要注意前面填过的数字结尾如果有 k 个6,通过后面拼接 3-k 个6也可以构成魔鬼数

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll f[21][4];
int T,n,l;
void init(){
f[0][0] = 1;
for(int i=1;i<=20;i++){
f[i][0] = 9*(f[i-1][0] + f[i-1][1] + f[i-1][2]);
f[i][1] = f[i-1][0];
f[i][2] = f[i-1][1];
f[i][3] = f[i-1][2] + 10 * f[i-1][3];
}
}
int main(){
init();
scanf("%d",&T);
while(T--){
scanf("%d",&n);
//l为答案的长度
for(l=3;f[l][3] < n;l++);
//k表示填过的数字末尾有k个6
for(int i=l,k=0;i;i--){
for(int j=0;j<=9;j++){
ll cnt = f[i-1][3];//后面预处理出的魔鬼数
//找能够拼凑出来的魔鬼数
if(j == 6 || k == 3){
if(k == 3){
for(int x = 0;x < 3;x++)
cnt += f[i-1][x];
}else{
for(int x = max(3-k-1, 0);x<3;x++){
cnt += f[i-1][x];
}
}
}
if(cnt < n) n -= cnt;
else{
if(k < 3) j == 6 ? k ++ : k=0;
printf("%d",j);break;
}
}
}
cout<<endl;
}
return 0;
}

POJ-3208 Apocalypse Someday (数位DP)的更多相关文章

  1. POJ 3689 Apocalypse Someday [数位DP]

    Apocalypse Someday Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 1807   Accepted: 87 ...

  2. poj3208 Apocalypse Someday 数位dp+二分 求第K(K <= 5*107)个有连续3个6的数。

    /** 题目:poj3208 Apocalypse Someday 链接:http://poj.org/problem?id=3208 题意:求第K(K <= 5*107)个有连续3个6的数. ...

  3. POJ 3208 Apocalypse Someday

    题意: 将含有连续的三个6的数称为不吉利数,比如666,1666,6662,但是6266吉利.则666为第一个不吉利数,输入整数n,求第n个不吉利数.(n <= 5*10^7) 解法: 如果是给 ...

  4. poj3208 Apocalypse Someday[数位DP]

    数位中出现至少3个连续的'6'的数字(称魔鬼数),询问满足要求的排名k的数. 经典题型.采用试填法. 递推做法:预处理出$i$位数字中满足要求的数(下记为'魔鬼数').对每一位都从0到9试一遍,然而卡 ...

  5. poj 3252 Round Numbers 数位dp

    题目链接 找一个范围内二进制中0的个数大于等于1的个数的数的数量.基础的数位dp #include<bits/stdc++.h> using namespace std; #define ...

  6. poj 3252 Round Numbers(数位dp 处理前导零)

    Description The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, P ...

  7. POJ 3252 Round Numbers(数位dp&amp;记忆化搜索)

    题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于 ...

  8. $POJ$3252 $Round\ Numbers$ 数位$dp$

    正解:数位$dp$ 解题报告: 传送门$w$ 沉迷写博客,,,不想做题,,,$QAQ$口胡一时爽一直口胡一直爽$QAQ$ 先港下题目大意嗷$QwQ$大概就说,给定区间$[l,r]$,求区间内满足二进制 ...

  9. POJ 3208-Apocalypse Someday(数位dp)

    题意:给定n,输出第n大包含666的数字. 分析:dp[i][j][k][l]表示 长度为i,当前位是否是6,前一位是否6,是否已经包含666,表示的数量,再用二分找出第n大的这样的数字. #incl ...

  10. POJ - 3252 - Round Numbers(数位DP)

    链接: https://vjudge.net/problem/POJ-3252 题意: The cows, as you know, have no fingers or thumbs and thu ...

随机推荐

  1. 基于nginx实现web服务器的双机热备

    1.适用场景 对于部署重要的服务,会使用两台服务器,互相备份,共同执行同一服务.当一台服务器出现故障时,可以由另一台服务器承担服务任务,从而在不需要人工干预的情况下,自动保证系统能持续提供服务.双机热 ...

  2. Oracle误删数据的恢复

    Oracle误删数据的恢复,分为两种方法:SCN和时间戳两种方法恢复. 一.通过SCN恢复删除且已提交的数据 1.获得当前数据库的SCN号 select current_scn from v$data ...

  3. LeetCode53 最大子序列问题

    题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和.     示例:     输入: [-2,1,-3,4,-1,2,1,-5,4],   ...

  4. Jenkins Android APP 持续集成体系建设二—自动部署、执行测试任务,关联打包任务

    经过上一遍博客我们知道了怎么使用Jenkins自动打包,但打完包之后,我们还需要对新包进行回归测试,确定新包有没有问题,然后才能发布包,那么,话不多说,我们先来新建个自动化回归测试任务 新包自动化回归 ...

  5. Mybatis的CRUD 增删改查

    目录 namespace 命名空间 select insert update delete Mybatis 官网: https://mybatis.org/mybatis-3/zh/getting-s ...

  6. 【Samba】共享服务器的搭建和相关权限设置

    1.查看防护墙 [root@zhang~ ]# /etc/init.d/iptables status   iptables:Firewall is not running.   如果没有关闭的话将他 ...

  7. ctfhub技能树—文件上传—文件头检查

    打开靶机 尝试上传一个php文件 抓包修改 放包 制作图片马 上传图片马,并修改文件类型为png 测试连接 查找flag 成功拿到flag

  8. [XAML] 使用 XAML 格式化工具:XAML Styler

    1. XAML 的问题 刚入门 WPF/UWP 之类的 XAML 平台,首先会接触到 XAML 这一新事物.初学 XAML 时对它的印象可以归纳为一个词:一坨. 随着我在 XAML 平台上工作的时间越 ...

  9. ts类与修饰符

    最近在用egret做游戏,就接触到了ts,刚开始的时候觉得类挺难的,毕竟大多数的JavaScript工程师工作中不怎么需要用到这个,但是学起来就不愿意撒手了,真香! typescript其实是es6的 ...

  10. 登陆到 SAP 系统后的用户出口

    增强类型:smod 增强名称:SUSR0001 组件(退出功能模块):EXIT_SAPLSUSF_001 功能:用户每次登陆SAP系统后都会调用这个SUSR0001增强,可以在FUNCTION EXI ...