Apocalypse Someday
定义一个数是合法的,当且仅当中间出现至少一个连续的大于三个的6,求第x个合法的数,\(x\leq 50,000,000\)
解
首先,注意到求第几个,即想到试填法,而试填法关键在于确定了这个状态下的方案数,记住这个,接下来就很好理解了。
显然要表现长度,又因为要表现合法,于是设\(f[i][j]\)表示有i位的数,状态为j(0表示最高位没有6,1有1个6,2表示有连续的两个6的不合法的数,3表示这是一个合法的数)的方案数,因此不难有
\]
\]
边界:\(f[0][0]=1\)
于是我们可以以此从高位到低位进行试填,数字从小到大,注意特判6,比如填到第i位,此处填了一个6,前面有2个连续的6紧挨着第i位,于是不但\(f[i-1][3]\)为合法的方案,还有\(f[i-1][1]+f[i-1][2]\),同理可推出前面有1个6,注意前面3个6时,不管这里填什么,方案都是\(f[i-1][0]+f[i-1][1]+f[i-1][2]+f[i-1][3]\)
#include <iostream>
#include <cstdio>
#define il inline
#define ri register
#define int long long
using namespace std;
int dp[21][4];
il int max(int,int);
il void read(int&),prepare();
main(){
int lsy;read(lsy),prepare();
while(lsy--){
int x;read(x);
int w(0),i,j,t6(0),cnt;
while(dp[w][3]<x)++w;
while(w){
for(i=0;i<10;++i){
cnt=dp[w-1][3];
if(i==6||t6>2)
for(j=max(2-t6,0);j<3;++j)
cnt+=dp[w-1][j];
if(cnt>=x){putchar(i+48);break;}
else x-=cnt;
}if(i==6)++t6;else if(t6<3)t6&=0;--w;
}putchar('\n');
}
return 0;
}
il int max(int a,int b){
return a>b?a:b;
}
il void prepare(){
dp[0][0]=1;
for(int i(1);i<=20;++i)
dp[i][1]=dp[i-1][0],dp[i][2]=dp[i-1][1],dp[i][3]=10*dp[i-1][3]+dp[i-1][2],
dp[i][0]=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2])*9;
}
il void read(int &x){
x&=0;ri char c;while(c=getchar(),c<'0'||c>'9');
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
}
Apocalypse Someday的更多相关文章
- POJ 3689 Apocalypse Someday [数位DP]
Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 1807 Accepted: 87 ...
- POJ3208 Apocalypse Someday
题意 Language:Default Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 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的数. ...
- POJ3208:Apocalypse Someday
传送门 很神奇的一道题,正解是AC自动机+数位DP,个人感觉POPOQQQ大爷的方法更方便理解. 按照一般套路,先搞个DP预处理,设$f[i][0/1/2/3]$分别表示对于$i$位数,其中有多少个前 ...
- POJ3208 Apocalypse Someday(二分 数位DP)
数位DP加二分 //数位dp,dfs记忆化搜索 #include<iostream> #include<cstdio> #include<cstring> usin ...
- POJ 3208 Apocalypse Someday
题意: 将含有连续的三个6的数称为不吉利数,比如666,1666,6662,但是6266吉利.则666为第一个不吉利数,输入整数n,求第n个不吉利数.(n <= 5*10^7) 解法: 如果是给 ...
- 【POJ3208】Apocalypse Someday
Description 666号被认为是神秘的"野兽之数",在所有以启示录为主题的大片中都是一个被广泛使用的数字.但是,这个数字666不能总是在脚本中使用,所以应该使用1666这样 ...
- poj3208 Apocalypse Someday[数位DP]
数位中出现至少3个连续的'6'的数字(称魔鬼数),询问满足要求的排名k的数. 经典题型.采用试填法. 递推做法:预处理出$i$位数字中满足要求的数(下记为'魔鬼数').对每一位都从0到9试一遍,然而卡 ...
- POJ-3208 Apocalypse Someday (数位DP)
只要某数字的十进制表示中有三个6相邻,则该数字为魔鬼数,求第X小的魔鬼数\(X\le 5e7\) 这一类题目可以先用DP进行预处理,再基于拼凑思想,用"试填法"求出最终的答案 \( ...
随机推荐
- Java 序列化和反序列化(一)Serializable 使用场景
目录 Java 序列化和反序列化(一)Serializable 使用场景 1. 最简单的使用:Serializable 接口 2. 序列化 ID 的问题 3. 静态字段不会序列化 4. 屏蔽字段:tr ...
- linux 创建用户并限制其访问目录
1.创建用户及访问目录 useradd test1 -d /usr/share/webapps/test -M 设置密码 passwd test1 将访问目录权限全部赋予用户 chown -R te ...
- 集合 HashMap 的原理,与 Hashtable、ConcurrentHashMap 的区别
一.HashMap 的原理 1.HashMap简介 简单来讲,HashMap底层是由数组+链表的形式实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的,如果定位到的数组位置不含链表 ...
- git提交遇到.suo文件无法提交的问题
这个只是我个人遇到的一个问题小记 由于最近做的项目使用VS编辑器的,在用它集成创建的项目里,每次提交都会有个后缀名为.suo的文件在修改的文件列表里.这时直接进行提交会报错, 1.我将xx.suo/x ...
- 从内部重启python脚本
我有一个基于python的GTK应用程序,可以加载几个模块.它是从(linux)终端运行的,如下所示: ./myscript.py --some-flag setting 用户可以从程序中下载(使用G ...
- css垂直居中设置
转载自大佬的文章:纯css实现垂直居中的几种方法(https://www.cnblogs.com/hutuzhu/p/4450850.html) 总结得很棒,有好几种方法自己没用过的,拷贝过来给自己看 ...
- 22-8-filter
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 随笔记录 shell脚本相关内容 2019-8-26
字符串截取: 假设变量为var=http://www.hao.com/123.htm1. # 号截取,删除左边字符,保留右边字符.echo ${var#*//}其中 var 是变量名,# 号是运算符, ...
- react使用阿里爸爸的iconfont时,不展示的问题
选择使用Unicode时: 正常使用如下,显示也是正常: <i className="iconfont"></i> 使用map去循环时,需将原本的,改成 ...
- JavaScript做个时间表 Date()
<span id="shiji"></span><script> window.setInterval("time()",5 ...