问题: windy数
时间限制: 1 Sec 内存限制: 512 MB
题面
题目描述
Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为
的正整数被称为 Windy 数。
Windy 想知道,在A和B之间,包括A和B,总共有多少个 Windy 数?
输入格式
一行两个数,分别为 A,B 。
输出格式
输出一个整数,表示答案。
样例输入
1 10
样例输出
9
题解
我的数位dp入门题,嗯,其实挺easy的。
设f[i][j]表示填了i位数,最高位是j的windy数的个数。
于是不考虑神特么的先导0问题单考虑一下临位差距至少为2的问题直接大力dp算出所有的值。
然后再来一遍大力dp,j从1-9循环累加答案就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #define int long long #define rint register int #define ll long long using namespace std; int f[20][15]={0},a,b; ll pw[15]; void prework() { pw[0]=1; for(rint i=1;i<=12;++i)pw[i]=pw[i-1]*10; for(rint i=0;i<=9;++i)f[1][i]=1; for(rint i=2;i<=11;++i)//枚举数位 for(rint j=0;j<=9;++j)//枚举最高位 for(rint k=0;k<=9;++k)//枚举上一个状态的最高位,本状态的次高位 if(abs(j-k)>=2)f[i][j]+=f[i-1][k]; } int count(int x) { int w=0,y,ans=0,pre; while(pw[w]<=x)++w;//求位数 for(rint i=1;i<w;++i)//枚举位数 for(rint j=1;j<=9;++j)//枚举最高位 ans+=f[i][j]; y=x/pw[w-1]; for(rint i=1;i<y;++i)ans+=f[w][i]; pre=y; x%=pw[w-1]; for(rint i=w-1;i>=1;--i) { y=x/pw[i-1]; for(rint j=0;j<y;++j) if(abs(j-pre)>=2) ans+=f[i][j]; if(abs(pre-y)<2)break; pre=y; x%=pw[i-1]; } return ans; } signed main() { scanf("%lld %lld",&a,&b); prework(); cout<<count(b+1)-count(a)<<endl; return 0; }