【poj3208-Apocalypse Someday】数位DP
题意:问你在所有包含666的数中,第n大的是多少。(1 ≤ n ≤ 50,000,000) 。开头几个是666, 1666, 2666, 3666, 4666, 5666…
题解:
这题可以用AC自动机,不知道这个怎么做。。
用了数位DP。
第一道自己好好调出来的数位DP。。哭泣
(一)先用DP预处理出含有666的k位数一共有多少个,不含有666的k位数一共有多少个。只用求一边就可以,另一边用总数来减。
然后for一遍,判断出第n大的是多少位数。
//d[0][i] 第一位不是6的i位数不含666总方案数
//d[1][i] 第一位是6...
//d[2][i] 连续两个6...
//d[3][i] 不含666的i位数的总方案数
//d[4][i] 含有666的i位数...
(二)填数(从左往右)。填的时候要记录前两位是什么。
分两种情况:
1.填的数中已经有666。则后面的位可以填有666和没有666的数。
2.没有666。
这个再分两种 (1)现在不要填6-->则后面必须有666
(2)现在填6 如果是xx6,则后面可以是66xxxx或含有666的数;如果是x66,则后面是6xxx或者66xxx或者含有666的数。如果是xx6,则后面是66xxx或者含有666的数。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std; typedef long long LL;
const int N=,D=;
LL d[][];
int n,ans[];
//d[0][i] 第一位不是6的i位数不含666总方案数
//d[1][i] 第一位是6...
//d[2][i] 连续两个6...
//d[3][i] 不含666的i位数的总方案数
//d[4][i] 含有666的i位数... int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
memset(d,,sizeof(d));
memset(ans,,sizeof(ans));
LL sum=;
d[][]=;d[][]=;d[][]=;d[][]=;d[][]=;
d[][]=*;d[][]=;d[][]=;d[][]=*;d[][]=;
for(int i=;i<=D;i++)
{
d[][i]=*d[][i-];
d[][i]=d[][i-];
d[][i]=d[][i-];
d[][i]=d[][i]+d[][i]+d[][i];
sum*=;
d[][i]=sum-d[][i];
}
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int k=;
for(LL i=;i<=D;i++)
if(d[][i]>n) {k=i;break;}
int now=,a=,b=;
bool ok=;
for(int i=;i<=k;i++)
{
if(i==k)
{
if(!ok) ans[k]=;
else ans[k]=n-now-;
break;
}
bool bk=;
for(int j=;j<=;j++)
{
if(!ok)
{
if(j!=)
{
if(now+d[][k-i]<n) now+=d[][k-i];
else ans[i]=j,bk=;
}
else
{
if(a== && b==)
{
if(now+d[][k-i]+d[][k-i]<n) now+=d[][k-i]+d[][k-i];
else ans[i]=j,bk=,ok=;
}
else if(a!= && b==)
{
if(now+d[][k-i]+d[][k-i]+d[][k-i]<n) now+=d[][k-i]+d[][k-i]+d[][k-i];
else ans[i]=j,bk=;
}
else //这里原本打了a、b都不等于6,WA,应该是b不等于6就可以了。
{
if(now+d[][k-i]+d[][k-i]<n) now+=d[][k-i]+d[][k-i];
else ans[i]=j,bk=;
}
}
}
else
{
if(now+d[][k-i]+d[][k-i]<n) now+=d[][k-i]+d[][k-i];
else ans[i]=j,bk=;
}
if(bk) break;
}
a=ans[i-],b=ans[i];
}
bool fir=;
for(int i=;i<=k;i++)
{
if(fir== && ans[i]==) continue;
if(fir== && ans[i]!=) fir=;
if(fir) printf("%d",ans[i]);
}
if(T) printf("\n");
}
return ;
}
【poj3208-Apocalypse Someday】数位DP的更多相关文章
- 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[数位DP]
数位中出现至少3个连续的'6'的数字(称魔鬼数),询问满足要求的排名k的数. 经典题型.采用试填法. 递推做法:预处理出$i$位数字中满足要求的数(下记为'魔鬼数').对每一位都从0到9试一遍,然而卡 ...
- POJ 3689 Apocalypse Someday [数位DP]
Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 1807 Accepted: 87 ...
- POJ3208 Apocalypse Someday(二分 数位DP)
数位DP加二分 //数位dp,dfs记忆化搜索 #include<iostream> #include<cstdio> #include<cstring> usin ...
- POJ3208 Apocalypse Someday
题意 Language:Default Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 2 ...
- POJ-3208 Apocalypse Someday (数位DP)
只要某数字的十进制表示中有三个6相邻,则该数字为魔鬼数,求第X小的魔鬼数\(X\le 5e7\) 这一类题目可以先用DP进行预处理,再基于拼凑思想,用"试填法"求出最终的答案 \( ...
- POJ 3208-Apocalypse Someday(数位dp)
题意:给定n,输出第n大包含666的数字. 分析:dp[i][j][k][l]表示 长度为i,当前位是否是6,前一位是否6,是否已经包含666,表示的数量,再用二分找出第n大的这样的数字. #incl ...
- 数位DP专题
这周开始刷数位DP,在网上找到一份神级数位DP模板,做起题目来爽歪歪. http://www.cnblogs.com/jffifa/archive/2012/08/17/2644847.html in ...
- 开坑数位dp
[背景] 在10月3日的dp专练中,压轴的第6题是一道数位dp,于是各种懵逼. 为了填上这个留存已久的坑,蒟蒻chty只能开坑数位dp了. [例题一][HDU2089]不要62 题目大意:给你一个区间 ...
- 数位dp真·浅谈 By cellur925
预警:由于是从$Vergil$学长那里和$Mathison$大神那里学来的,所以清一色记忆化搜索!qwq 巨佬的数位dp讲解(未来的咕咕日报头条): https://www.luogu.org/blo ...
随机推荐
- ssh 安装
一 ssh 1.查看ssh服务的状态 输入以下命令: sudo service sshd status 如果出现 Loaded: error (Reason: No such file or dire ...
- mac os x 系统安装 genymotion android 模拟器
如果你有 apk 文件 想 运行一下看看 ,但是又没有 android 设备 ,那么 genymotion 将会是一个 很好的解决方案. 1.安装 下载链接: https://cloud.geny ...
- LNMP下wordpress无法切换主题,只显示当前主题解决方法
最近在lnmp下发现wordpress后台无法切换主题,只能显示当前主题,开始还以为是文件没传完,又重置了一遍,还是一样.百度得知,原来军哥的LNMP安装包默认关闭了scandir函数,为了安全考虑. ...
- 无法加载一个或多个请求的类型。有关更多信息,请检索 LoaderExceptions 属性
一解决方法: 问题的主要原因出在:跨程序集反射. 即我们需反射的A.dll的程序集引用B.dll程序集,而在反射工具项目中却不存在对B.dll程序集的引用.因此我们只需在反射工具项目中添加对B.dll ...
- verilog实现16位五级流水线的CPU带Hazard冲突处理
verilog实现16位五级流水线的CPU带Hazard冲突处理 该文是基于博主之前一篇博客http://www.cnblogs.com/wsine/p/4292869.html所增加的Hazard处 ...
- PB串口编程资料(转)
----MSCOMM32参数基本介绍2008年03月29日 星期六 上午 11:37MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能.MSComm控件在串口编程时非常方便,程序 ...
- springboot快速搭建
环境 spring-boot-starter-parent 是一个特殊的starter,它提供了有用的Maven默认设置.同时,它也提供了一个 dependency-management 节点,这样对 ...
- 说明&总目录
1. 说明 1.1 这是一个乱七八糟的博客,包含遇到的各类问题,甚至会有奇♂怪的东西~ 1.2 作者目前本科生,懒虫一只,喜欢吃喝玩乐看动漫,更喜欢睡觉 1.3 文章难免有错,欢迎指出 1.4 语死早 ...
- xml之XSLT
1.XSLT是什么 XSLT是XSL的子集,XSL是样式表.XSLT的作用:将XML文档转化成HTML,做的是中间转换者. 而主要需要学习的是XSLT(XSLTransformation). 2 ...
- android开发 drawtext的开始坐标位置
我们canvas绘制文字的遇到一个不知道drawtext(str,x,y,paint) 中的x.y坐标值怎么定义,,如果设为(0,0)的话文字就不会出来了.因此查找到一下资料: 问:canvas.d ...