洛谷P2188 小Z的 k 紧凑数
题目描述
小 Z 在草稿纸上列出了很多数,他觉得相邻两位数字差的绝对值不超过 k 的整数特别奇特,称其为 k 紧凑数。
现在小 Z 想知道 [l,r] 内有多少个 k 紧凑数,希望你帮帮他。
输入输出格式
输入格式:
第一行包含三个整数 l,r,k。
输出格式:
第一行包含一个整数,表示 [l,r] 内 k 紧凑数的个数。
输入输出样例
输入样例#1:
1 13 1
输出样例#1:
12
说明
【数据规模】
对于 30% 的数据,r − l ≤ 10^5;
对于另外 30% 的数据,l = 1,r 为 10 的倍数;
对于 100% 的数据,1 ≤ l ≤ r ≤ 10^18,0 ≤ k ≤ 8。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> using namespace std; long long l,r; int k,len,bin[20],b[20]; long long dfs(int pos,int pre,int limit,int lead){ if(pos==len+1)return 1; int end=limit?bin[pos]:9; long long ans=0; if(pos==1){ for(int i=0;i<=end;i++) ans+=dfs(pos+1,i,limit&&i==end,lead&&i==0); } else if(lead){ for(int i=0;i<=end;i++) ans+=dfs(pos+1,i,limit&&i==end,lead&&i==0); } else{ for(int i=max(0,pre-k);i<=min(pre+k,end);i++) ans+=dfs(pos+1,i,limit&&i==end,lead&&i==0); } return ans; } long long work(long long x){ len=0; while(x){ b[++len]=x%10; x/=10; } for(int i=1,j=len;i<=len;i++,j--)bin[i]=b[j]; return dfs(1,0,1,1); } int main(){ freopen("Cola.txt","r",stdin); scanf("%d%d%d",&l,&r,&k); cout<<work(r)-work(l-1); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> #include<cstdlib> #define int long long using namespace std; int f[21][11],x,y,m,bin[21]; int dp(int x){ if(x==0)return 1; bin[0]=0;while(x)bin[++bin[0]]=x%10,x/=10; if(bin[0]==1)return bin[1]+1; int ans=1; for(int i=1;i<bin[0];i++) for(int j=1;j<10;j++)ans+=f[i][j]; for(int i=1;i<bin[bin[0]];i++)ans+=f[bin[0]][i]; for(int i=bin[0]-1;i;i--){ if(i<bin[0]-1&&abs(bin[i+1]-bin[i+2])>m)return ans; for(int j=0;j<bin[i];j++)if(abs(j-bin[i+1])<=m)ans+=f[i][j]; } if(abs(bin[1]-bin[2])<=m)ans++;return ans; } signed main(){ freopen("Cola.txt","r",stdin); cin>>x>>y>>m; for(int i=0;i<10;i++)f[1][i]=1; for(int i=2;i<=18;i++) for(int j=0;j<10;j++) for(int k=0;k<10;k++)if(abs(j-k)<=m)f[i][j]+=f[i-1][k]; cout<<dp(y)-dp(x-1); return 0; }