POJ3208 Apocalypse Someday Solution
来源:互联网 发布:mysql查看所有表空间 编辑:程序博客网 时间:2024/05/29 16:07
题目大意:
求出第k小的包含有'666'的正整数。k<=5*10^7.
Sol:
将问题转化在KMP自动机上。
存在四个节点,0,1,2,3,分别表示当前前缀匹配6的个数为0,1,2,3。其中3是接受状态。
注意从3出发的任何转移均回到自身。此外0.go[6]=1,1.go[6]=2,2.go[6]=3.此外的转移均为0.
随后,我们预处理出从状态i出发走j步到达接受状态的个数num[i][j]。
而且,容易算出长度为i的能够到达接受状态的总数tot[i]。
对于每一个n,我们首先确定这是几位数。
随后从高到低对位进行枚举。如何确定这一位的数字是多少呢?
从小到大进行尝试,设当前状态为p,枚举数字为j,当前位数为i,要求剩下的第k大,那么:
若num[p.go[j]][i]>=k,证明这一位为j,p=p.go[j];否则k-=num[p.go[j]][i].
分析算法的时间复杂度:预处理O(logn),对于每组询问O(log^2n),轻松水过。
Code:
#include <cstdio>#include <cstring>#include <cctype>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;int go[4][10];#define Len 10LL tmp[Len + 1][4], sav[4][Len + 1], tot[Len + 1];const int ch[] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0};inline void pre() {register int i, j, k, p;go[0][6] = 1, go[1][6] = 2, go[2][6] = 3;for(i = 0; i < 10; ++i)go[3][i] = 3;for(i = 0; i < 4; ++i) {memset(tmp, 0, sizeof(tmp));tmp[0][i] = 1;for(j = 0; j < Len; ++j)for(k = 0; k < 4; ++k)for(p = 0; p < 10; ++p)tmp[j + 1][go[k][p]] += tmp[j][k];for(int len = 1; len <= Len; ++len)sav[i][len] = tmp[len - 1][3];}for(i = 1; i <= Len; ++i)for(j = 1; j < 10; ++j)tot[i] += sav[ch[j]][i];}int main() {pre();register int i, j;int n, T, len;scanf("%d", &T);while(T--) {int n;scanf("%d", &n);for(len = 3; len <= Len; ++len) {if (tot[len] >= n)break;n -= tot[len];}int now = 0;for(i = len; i >= 1; --i) {int lim = (i == len);for(j = lim; j < 10; ++j) {if (n <= sav[go[now][j]][i]) {now = go[now][j];printf("%d", j);break;}n -= sav[go[now][j]][i];}}puts("");}return 0;}
0 0
- POJ3208 Apocalypse Someday Solution
- poj3208 Apocalypse Someday
- 数位DP POJ3208 Apocalypse Someday
- [POJ3208]Apocalypse Someday-二分-数位DP
- POJ 3208 Apocalypse Someday
- POJ 3208 Apocalypse Someday
- Poj 3208 Apocalypse Someday
- POJ 3208 Apocalypse Someday
- poj 3208 (666) Apocalypse Someday
- poj 3208 Apocalypse Someday (数位dp)
- poj 3208 Apocalypse Someday(数位dp)
- POJ 3208 Apocalypse Someday(数位DP)
- POJ 3208 Apocalypse Someday(数位dp)
- poj 3208 Apocalypse Someday 自动机+dp
- Apocalypse Someday (数位dp+二分)
- poj 3208 Apocalypse Someday(数位DP,4级)
- POJ 3208 Apocalypse Someday 二分答案+数位DP
- poj 3208 Apocalypse Someday (数位dp+二分答案)
- 关于文件在内存中读写的问题
- DELPHI把一个字符串中的某个子串,用另一个子串去替换
- Task Affinity
- 几种分布式调用技术的比较 -- RPC VS REST
- flume 安装
- POJ3208 Apocalypse Someday Solution
- 【悠然】对虚拟目录 虚拟主机的理解 2014.08.19 20;40;20
- Delphi更新本地时间
- AutoCompleteTextView中的弹出框实现模糊查询
- Fragment上下文菜单示例
- FreeMarker
- 模板方法设计模式
- 面向对象
- MeasureSpec介绍及使用详解