Windy 数:不含前导零且相邻两个数字之差至少为 2 的正整数被称为 Windy 数。
在 A 和 B 之间,包括 A 和 B,总共有多少个 Windy 数?
- #include <bits/stdc++.h>
-
- using namespace std;
-
- int nums[20];
- int dp[20][10];
- /*dp[i][j] 当前数字为第i位,前一位数字为j
- 满足不含前导0且相邻两个数差大于等于2的数的个数
- */
- int dfs(int pos,int pre,bool lead,bool lim){
- if(pos<0)
- return 1;
- if(!lim&&!lead&&dp[pos][pre]!=-1)
- return dp[pos][pre];
- int end=(lim?nums[pos]:9);
- int res=0;
- for(int i=0;i<=end;i++){
- if(lead){
- if(i==0)
- res+=dfs(pos-1,0,true,lim&&(end==i));
- else
- res+=dfs(pos-1,i,false,lim&&(end==i));
- }
- else{
- if(abs(i-pre)>=2)
- res+=dfs(pos-1,i,false,lim&&(end==i));
- }
- }
- if(!lim&&!lead)
- dp[pos][pre]=res;
- return res;
- }
- int solve(int x){
- int cnt=0;
- while(x){
- nums[cnt++]=x%10;
- x=x/10;
- }
- int res=dfs(cnt-1,0,true,true);
- }
- int main(){
- memset(dp,-1,sizeof(dp));
- int a,b;
- scanf("%d%d",&a,&b);
- int ans=solve(b)-solve(a-1);
- printf("%d\n",ans);
-
- }
求两个数a和b之间数位满足某种关系的数的个数
步骤:
1.确定dp[i][j]的含义,编写dfs函数
dfs函数中:
1)返回条件
2)当不为特殊条件(如题中!lim-非右树,!lead-非前导零),且dp[i][j]不为初始值,直接返回dp[i][j]
3) 否则说明当前形参对应的值需要计算
若该位的lim为true(说明该数位的是最右链上的点,当前pos能取到的最大数就是nums[pos],否则能去到最大值),之后用for循环从0-end枚举每一位可能的值,计算res
4)当不为特殊条件,直接令dp[i][j]=res,下次就无需再计算
5)返回res
2.对数b,将各数位进行分解保存到nums数组中(具体怎么分解根据题意要求)
调用dfs计算[1,b]满足条件的数的个数,同理计算[1,a-1]的,两者相减就得到答案。