题目链接: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. RStudio:R语言编辑器

    RStudio:R语言编辑器 四窗口 左上:写代码,运行的方式是ctrl+Enter,或者用Run按钮 10 + 15 ## [1] 25 左下:终端,上面窗口的代码运行后会在这里显示,也可以直接在这 ...

  2. java基础理论知识的一些总结

    在学习Java初期,由于我们是刚开始接触Java,我们不仅需要牢牢掌握Java的基础理论知识,来为我们后面对Java更深层次的学习打好基础,而且我们需要养成编程人的思想习惯.来我们一起来探索Java基 ...

  3. 放弃移动版Flash而非AIR

    之前看到标题为"Adobe放弃移动版flash"的新闻,我很震惊,为何Adobe会放弃这么一个大市场呢? 这样无疑打击原来在flash的开发上的应用,我想很多人和我想的一样,fla ...

  4. Hdu 5444 Elven Postman dfs

    Elven Postman Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  5. 滑雪_poj_1088(记忆化搜索).java

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 67987   Accepted: 25013 Description ...

  6. callerloc

    callerloc An Android app to show location info of incoming calls or outgoing calls in a floating win ...

  7. [JavaScript]'this'详解

    http://blog.csdn.net/sodino/article/details/51318565

  8. 启动android程序和虚拟机时候出现如下错误的解决方法

    启动android程序和虚拟机时候出现如下错误的解决方法. 错误重现: [2011-07-13 16:22:48 - Emulator] invalid command-line parameter: ...

  9. Class File Editor: Source not found

    问题: 找不到需要的 *.java 文件就会报以下错误. 解决方案: 1. Window -> preferences -> Java -> Installed JREs 2. 选择 ...

  10. 手动开启tomacat服务器

    四.配置Tomcat环境变量 1,新建变量名(关键,你的tomacat安装目录):CATALINA_BASE,变量值:E:\apache-tomcat-6.0.37 2,新建变量名(关键,你的toma ...