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的数。
思路:数位dp+二分。
dp[i][j]表示长度为i,前缀状态为j时含有的个数。
j=0表示含有前导0;
j=1表示前缀连续1个6
j=2表示前缀连续2个6
j=3表示前缀连续3个6
j=4表示前缀不是6; */ //#include<bits/stdc++.h>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
#define P pair<int,int>
#define ms(x,y) memset(x,y,sizeof x)
#define LL long long
const int maxn = ;
const int mod = 1e9+;
const int maxnode = *+;
const int sigma_size = ;
const LL inf = 1e18;
int digit[];
LL dp[][];///0表示前导0,1表示前缀一个6,2表示前缀2个6,3表示前缀3个6,4表示前缀不是6;
int next_state(int state,int x)
{
if(state==) return ;
if(x==){
if(state==||state==) return state+;
else return ;
}else
{
return ;
}
}
LL dfs(int len,int state,int bounded)
{
if(len==){
return state==;
}
if(!bounded&&dp[len][state]!=-) return dp[len][state];
int d = bounded?digit[len]:;
LL ans = ;
for(int i = ; i <= d; i++){
if(state==){
if(i==) ans += dfs(len-,,bounded&&(i==d));
else ans += dfs(len-,i==?:,bounded&&(i==d));
}else
{
ans += dfs(len-,next_state(state,i),bounded&&(i==d));
}
}
if(!bounded){
dp[len][state] = ans;
}
return ans;
}
LL solve(LL n)
{
int len = ;
while(n){
digit[++len] = n%;
n /= ;
}
return dfs(len,,true);
}
int main()
{
int T;
ms(dp,-);
cin>>T;
while(T--)
{
int n;
scanf("%d",&n);
LL lo = , hi = inf, mi;
while(lo<hi){
mi = (lo+hi)/;
LL ans = solve(mi);
if(ans>=n){///找下界。
hi = mi;
}else
{
lo = mi+;
}
}
printf("%lld\n",hi);
}
return ;
} /* */
poj3208 Apocalypse Someday 数位dp+二分 求第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 ...
- POJ-3208 Apocalypse Someday (数位DP)
只要某数字的十进制表示中有三个6相邻,则该数字为魔鬼数,求第X小的魔鬼数\(X\le 5e7\) 这一类题目可以先用DP进行预处理,再基于拼凑思想,用"试填法"求出最终的答案 \( ...
- POJ3208 Apocalypse Someday
题意 Language:Default Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 2 ...
- UPC 2223: A-Number and B-Number(数位DP+二分)
积累点: 1: (l&r)+((l^r)>>) == (l+r)/2 2: 注意判断现在是否有限制.当枚举下一个量时,是(isQuery && j==end),不要 ...
- hihocoder #1301 : 筑地市场 数位dp+二分
题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostr ...
- 数位dp(求1-n中数字1出现的个数)
题意:求1-n的n个数字中1出现的个数. 解法:数位dp,dp[pre][now][equa] 记录着第pre位为now,equa表示前边是否有降数字(即后边可不能够任意取,true为没降,true为 ...
- CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)
All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...
随机推荐
- HDUOJ-----1556Color the ball
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- Android 中发送短信
import android.net.Uri; //调用Android系统API发送短信 Uri uri = Uri.parse("smsto:" + strSmsPhone_va ...
- BIP_BI Pubisher的SQL/XSL/FO扩展函数应用(概念)
2014-12-01 Created By BaoXinjian
- AP_应付模组在月结的处理
2014-06-04 Created By BaoXinjian 1. 完成所有交易及检查Interface (1). Invoice and Credits (2). Prepa ...
- OAF_OAF控件系列9 - Description Flexfiled描述性弹性域的实现(案例)
2014-06-17 Created By BaoXinjian
- C语言中续行符“\”说明
把一个预处理指示写成多行要用“\”续行,因为根据定义,一条预处理指示只能由一个逻辑代码行组成. 而把C代码写成多行则不必使用续行符,因为换行在C代码中只不过是一种空白字符,在做语法解析时所有空白字符都 ...
- mac重装系统
通过 macOS 恢复功能启动macOS 恢复功能会根据您在电脑启动时按下的组合键来安装不同版本的 macOS.在按电源按钮打开 Mac 后,立即按住以下组合键之一.然后在看到 Apple 标志或旋转 ...
- sqlite时间戳转时间语句(时间转时间戳)实例
sqlite时间戳转时间.时间转时间戳的方法 实现代码: sqlite, 'unixepoch', 'localtime'); +----------------------------------- ...
- CSS实现超级链接需要通过双击后跳转
超级链接需要双击后跳转如何实现. CSS代码.test3 span { position: relative;}.test3 span a { position: relative;z-index: ...
- 批处理学习笔记7 - 管道连接符"|"
|就是把左边作为值传递给右边.有一些命令运用它比较方便 @echo off ping baidu.com | find "TTL" pause 这段命令就是把左边ping的结果传递 ...