题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3943

题目大意:求出区间 (P,Q] 中找到第K个满足条件的数,条件是该数包含X个4和Y个7

Sample Input
1
38 400 1 1
10
1
2
3
4
5
6
7
8
9
10
 
Sample Output
Case #1:
47
74
147
174
247
274
347
374
Nya!
Nya!

分析一:

  先预处理dp[i][j][k]表示第 i 位有 j 个4和 k 个7的数量。之后就可以通过高位开始枚举,求出区间内有多少个规定的数,如果询问大于总数,则输出“Nya!”

  之后找第k大的数:首先可以确定出位数,dp[i][x][y]表示 i 位时的满足数,那么大于dp[len-1][x][y],而小于dp[len][x][y],len表示目标位数。

  确认了位数之后,依然从高位开始。比如说高位首先是0,而dp[len-1][x][y]小于k,说明0开头的目标小于所求,继续往后找,把之前的删掉

  有点意思

代码如下:

 # include<iostream>
# include<cstdio>
# include<cstring>
# define LL __int64
using namespace std; LL dp[][][]; //dp[i][j][k]表示i位的数,有j个4,k个7的数量
LL l,r;
int x,y; void init()
{
int i,j,k;
memset(dp,,sizeof(dp));
dp[][][] = ;
for(i=; i<=; i++)
for(j=; j<i; j++)
for(k=; k+j<i; k++)
{
dp[i][j][k+] += dp[i-][j][k];
dp[i][j+][k] += dp[i-][j][k];
dp[i][j][k] += dp[i-][j][k]*; //在高位上加除4、7以外的8个数字
}
} LL get_count(LL n)
{
int bit[],len=;
while(n)
{
bit[++len] = n%;
n /= ;
}
LL ans = ;
int cx=x, cy=y;
for(int i=len; i; i--) //从高位开始枚举
{
for(int j=; j<bit[i]; j++)
if(j==)
{
if(cx)
ans += dp[i-][cx-][cy];
}
else if(j==)
{
if(cy)
ans += dp[i-][cx][cy-];
}
else
ans += dp[i-][cx][cy];
if(bit[i]==)
cx--;
if(bit[i]==)
cy--;
//如果高位出现的4、7的数量已经超过所求,则退出
if(cx< || cy<)
break;
}
return ans;
} LL solve(LL k)
{
int len = ;
while()
{
//找到目标长度
if(dp[len-][x][y]<k && dp[len][x][y]>=k)
break;
len++;
}
LL ret = ;
int cx=x, cy=y;
for(int i=len; i; i--)
{
//从高位开始枚举
for(int j=; j<; j++)
{
int tx = cx,ty=cy;
if(j==)
{
tx--;
if(tx<)
continue;
}
if(j==)
{
ty--;
if(ty<)
continue;
}
if(dp[i-][tx][ty] >= k)
{
ret = ret*+j;
cx=tx;
cy=ty;
break;
}
k -= dp[i-][tx][ty];
}
}
return ret;
} int main()
{
init();
int T,cas;
scanf("%d",&T);
for(cas=; cas<=T; cas++)
{
scanf("%I64d%I64d%d%d",&l,&r,&x,&y);
LL a=get_count(r+);
LL b=get_count(l+); //注意左开区间
int n;
scanf("%d",&n);
printf("Case #%d:\n",cas);
while(n--)
{
LL k;
scanf("%I64d",&k);
if(k > a-b)
puts("Nya!");
else
printf("%I64d\n",solve(k+b));
}
}
return ;
}

 分析二:

  将solve() 函数改成二分写法,答案更简洁

 LL solve(LL k)
{
LL mid,ans=-,ret,left=l,right=r;
while(left<=right)
{
mid = (left+right)>>;
ret = get_count(mid+);
if(ret>=k)
{
ans =mid;
right = mid-;
}
else
left=mid + ;
}
return ans;
}

HDU 3943 K-th Nya Number(数位DP)的更多相关文章

  1. 多校5 HDU5787 K-wolf Number 数位DP

    // 多校5 HDU5787 K-wolf Number 数位DP // dp[pos][a][b][c][d][f] 当前在pos,前四个数分别是a b c d // f 用作标记,当现在枚举的数小 ...

  2. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  3. HDU 5787 K-wolf Number 数位DP

    K-wolf Number Problem Description   Alice thinks an integer x is a K-wolf number, if every K adjacen ...

  4. HDU 3709 Balanced Number (数位DP)

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  5. HDU 5179 beautiful number 数位dp

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...

  6. hdu 5898 odd-even number(数位dp)

    Problem Description For a number,if the length of continuous odd digits is even and the length of co ...

  7. HDU 5898 odd-even number (数位DP) -2016 ICPC沈阳赛区网络赛

    题目链接 题意:一个数字,它每个数位上的奇数都形成偶数长度的段,偶数位都形成奇数长度的段他就是好的.问[L , R]的好数个数. 题解:裸的数位dp, 从高到低考虑每个数位, 状态里存下到当前位为止的 ...

  8. codeforces Hill Number 数位dp

    http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits: ...

  9. beautiful number 数位DP codeforces 55D

    题目链接: http://codeforces.com/problemset/problem/55/D 数位DP 题目描述: 一个数能被它每位上的数字整除(0除外),那么它就是beautiful nu ...

  10. Fzu2109 Mountain Number 数位dp

    Accept: 189    Submit: 461Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description One ...

随机推荐

  1. 命令删除visualstudio.com云端项目(TFS)

    1.运行命令行 2.tfsdeleteproject /collection:https://域名.visualstudio.com/DefaultCollection “项目名称”

  2. Oracle- 存储过程和异常捕捉

    这段时间晚上有时候去打打球,回家看看电视剧,日子一天天过…….学了点ORACLE存储过程基础,作一下备注,以便日后需查阅. 创建无参存储过程 create procedure p_myPro1 is ...

  3. RocketMQ入门(1)

    转自:http://www.changeself.net/archives/rocketmq入门(1).html RocketMQ入门(1) RocketMQ是一款分布式.队列模型的消息中间件,具有以 ...

  4. .NET解析HTML库集合

    CsQuery AngleSharp Jumony HtmlAgilityPack Fizzler ScrapySharp NSoup

  5. ecshop中index.dwt文件分析

    对于ecshop新手来说,这篇总结值得关注. 对于没有web编程基础的同学来说,ecshop模板里面有两个文件特别重要, 但是这两个文件同时也很不好理解,分别是index.dwt和style.css. ...

  6. 拼接json示例 json分页并显示所有页码

    <%@ page language="java" import="java.util.*" pageEncoding="gbk"%&g ...

  7. git拉取远程分支并创建本地分支和Git中从远程的分支获取最新的版本到本地

    git拉取远程分支并创建本地分支 一.查看远程分支 使用如下Git命令查看所有远程分支: git branch -r 二.拉取远程分支并创建本地分支 方法一 使用如下命令: git checkout ...

  8. bzoj 1800: [Ahoi2009]fly 飞行棋 暴力

    1800: [Ahoi2009]fly 飞行棋 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  9. css固定表格表头(各浏览器通用)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. linux 参数优化

    脏页 vm.dirty_background_radio=10 (当脏页占内存10%,pdflush工作) vm.dirty_radio=40 (当进程自身脏页占内存40%,进程自己处理脏页,将其写入 ...