博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
windy数
阅读量:5303 次
发布时间:2019-06-14

本文共 1078 字,大约阅读时间需要 3 分钟。

不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

这是一道数位dp,设dp[i][j],dp[i][j]表示i为长度,j为最高位上的数字的个数。

#include<stdio.h>

#include<string.h>
#include<math.h>
int dp[100][14];
void init()
{
int i,j,k;
memset(dp,0,sizeof(dp));
for(j=0;j<=9;j++)dp[1][j]=1;
for(i=2;i<=11;i++){
for(j=0;j<=9;j++){        //这里要注意不能从j=1开始循环,因为10010这样是符合条件的,但0010的最高位0是0 
for(k=0;k<=9;k++){
if(fabs(j-k)>1){
dp[i][j]+=dp[i-1][k];
}
}
}
}
}
int cal(int x)  //计算的是(0,a)区间的windy数 
{
int m=0,i,j,a[100],ans=0;
memset(a,0,sizeof(a));
while(x>0){
a[++m]=x%10;
x=x/10;
}
for(i=1;i<=m-1;i++){       //先算数字长度小于m的windy数 
for(j=1;j<=9;j++){     //因为不含前导0,所以从j=1开始算 
ans=ans+dp[i][j];
}
}
for(j=1;j<a[m];j++){     //再算数字长度等于m但最高位小于a[m]的windy数 
ans=ans+dp[m][j];
}
for(i=m-1;i>=1;i--){   //最后一次将最高位变成和原来的数一样,就是接近原来的数 
for(j=a[i]-1;j>=0;j--){    
if(fabs(a[i+1]-j)>1){
ans=ans+dp[i][j];
}
}
if(fabs(a[i]-a[i+1])<=1)break;  //如果这个时候前面的数字不符合windy数的要求,后面的数也一定不符合 
}
return ans;
}
int main()
{
int n,m,i,j;
init();
while(scanf("%d%d",&n,&m)!=EOF)
{
printf("%d\n",cal(m+1)-cal(n));
}
return 0;
}

转载于:https://www.cnblogs.com/herumw/p/9464840.html

你可能感兴趣的文章
手工卸载.Net写的win服务
查看>>
步步为营99-不同数据库数据实时同步
查看>>
jzoj 高中 3505——积木
查看>>
[高精度][规律][二分] Jzoj P4213 对你的爱深不见底
查看>>
java堆和栈
查看>>
WebDriver--简单的元素操作
查看>>
不要把大脑当做磁盘【转文】
查看>>
关于递归运算的顺序
查看>>
05_ssm基础(三)之Spring基础
查看>>
【HackerRank】Maximizing XOR
查看>>
如何在C/C++中动态分配二维数组
查看>>
Visual FoxPro权威指南pdf
查看>>
hdu 4283 You Are the One 区间DP
查看>>
SSH客户端,FinalShell服务器管理,远程桌面加速软件,支持Windows,Mac OS X,Linux,版本2.6.3.1...
查看>>
(转)表单元素与提示文字无法对齐的问题(input,checkbox文字对齐)
查看>>
实验 5 编写、调试具有多个段的程序
查看>>
[USACO 2012 Jan Silver] Bale Share【DP】
查看>>
office outlook 2010 设置开机自动启动并最小化——隐藏于任务栏通知区域
查看>>
Educational Codeforces Round 52 (Rated for Div. 2) D. Three Pieces
查看>>
day33
查看>>