【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 ...
随机推荐
- having count group by
select count(*) from (select field2,count(field2) from bsgj.table1 group by field,items_id having(c ...
- [转]windows 软链接的建立及删除
[转]windows 软链接的建立及删除 http://blog.chinaunix.net/uid-74941-id-3764093.html 1.建立举例 ##建立d:develop链接目录,指向 ...
- Linq To SQLite by CRUD
1, 希望使用linqtoSQLite 来对数据库实现CRUD, 开发环境 VS2013, 1.1 在网上找到了 LINQ to DB T4 Models, 配置参考网址链接: http://www. ...
- FPGA---ucf文件编写
摘要:本文主要通过一个实例具体介绍ISE中通过编辑UCF文件来对FPGA设计进行约束,主要涉及到的约束包括时钟约束.群组约束.逻辑管脚约束以及物理属性约束. Xilinx FPGA设计约束的分类 Xi ...
- 邻接矩阵实现Dijkstra算法以及BFS与DFS算法
//============================================================================ // Name : MatrixUDG.c ...
- USB硬件远程共享解决iphone已停用
悲剧的在iphone拆过电池之后,再开机显示iphone已停用,请在23000000分钟后再试一次 算算这得45年了,可以留给孙子用了... 网上除了刷机和有同步过的电脑貌似没有别的办法了 因是旧系统 ...
- 网络服务器带宽Mbps、Mb/s、MB/s有什么区别?10M、100M到底是什么概念?
网络服务器带宽Mbps.Mb/s.MB/s有什么区别?我们经常听到IDC提供的服务器接入带宽是10M独享,或者100M独享,100M共享之类的数据.这的10M.100M到底是什么概念呢? 工具/原料 ...
- hdu 4240 Route Redundancy 最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4240 A city is made up exclusively of one-way steets. ...
- 【BZOJ】【1015】 【JSOI2008】星球大战starwar
并查集/时光倒流 删点维护连通块个数比较难处理,所以我们就逆序来做,先处理最后状态下有多少连通块,再依次加入被删的点,这样就变删点为加点,利用并查集即可维护连通块个数. /************** ...
- Oracle 11g安装与使用
作为一个新手,学习Oracle,就连安装oracle都感觉到吃力! 经过不间断的搜罗.学习.尝试,找到一些比较有用的“指导”,罗列如下: 1. http://www.2cto.com/database ...