本人水平有限,题解不到为处,请多多谅解
本蒟蒻谢谢大家观看
传送门:
https://www.luogu.org/problem/P2657
题意有点恶心:是说某一个数,其每一位上的相邻的数字之差大于或等于2
和第一题lucky一样 设个f[i][j] : f[i][j]表示取i位的首位数字是j
转移就if(abs(j-k)>=2) f[i][j]+=f[i-1][k];
初值就个位数都是windy数
此题仍然需要用前缀和 即:sum(b+1)-sum(a) ;
预处理:f[1][i]=1因为个位数都满足题意
如果不明白转移可看我的第一题【NOIP 模拟题】lucky
博客:https://www.cnblogs.com/nlyzl/p/11262311.html
code:
#include<bits/stdc++.h> using namespace std; long long a,b; int n,m,t; int sum[100010]; int f[1001][1001]; int put(int x) { memset(sum,0,sizeof(sum)); int tl=x,tot=0,ans=0; while(tl) { sum[++tot]=tl%10; tl/=10; } for(int i=1;i<tot;i++) for(int j=1;j<=9;j++) ans+=f[i][j]; for(int i=1;i<sum[tot];i++) ans+=f[tot][i]; for(int i=tot-1;i;i--) { for(int j=0;j<sum[i];j++) if(abs(j-sum[i+1])>=2) ans+=f[i][j]; if(abs(sum[i]-sum[i+1])<2) break; } return ans; } int main() { scanf("%lld%lld",&a,&b); t=b; while(t) { m++; t/=10; } for(int i=0;i<=9;i++) f[1][i]=1; for(int i=1;i<=m;i++) for(int j=0;j<=9;j++) for(int k=0;k<=9;k++) if(abs(j-k)>=2) f[i][j]+=f[i-1][k]; printf("%d ",put(b+1)-put(a)); return 0; }