题目描述
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
输入输出格式
输入格式:
包含两个整数,A B。
输出格式:
一个整数
思路:
数位DP模板
先预处理每一个长度有多少个windy数
然后分别处理两个比边界数小的windy数有几个(类似前缀和)
怎么处理呢?
比他们位数小的,加起来就好
位数一样的,则每一位考虑
当前位与i+1位的差的绝对值大于等于2是就加上
否则跳出
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define rii register int i #define rij register int j #define rik register int k using namespace std; long long dp[15][15],l,r,every[15]; void ycl() { for(rii=0;i<=9;i++) { dp[1][i]=1; } for(rii=2;i<=14;i++) { for(rij=0;j<=9;j++) { for(rik=0;k<=9;k++) { if(abs(j-k)>=2) { dp[i][j]+=dp[i-1][k]; } } } } } long long da(long long an) { long long ans=0; memset(every,0,sizeof(every)); int length=0; while(an) { length++; every[length]=an%10; an/=10; } for(rii=1;i<=length-1;i++) { for(rij=1;j<=9;j++) { ans+=dp[i][j]; } } for(rii=1;i<=every[length]-1;i++) { ans+=dp[length][i]; } for(rii=length-1;i>=1;i--) { for(rij=0;j<=every[i]-1;j++) { if(abs(j-every[i+1])>=2) { ans+=dp[i][j]; } } if(abs(every[i+1]-every[i])<2) { break; } } return ans; } int main() { scanf("%lld%lld",&l,&r); ycl(); long long ans=da(r+1); ans-=da(l); cout<<ans; }