题目大意:求[a,b]区间内有多少个数满足任意相邻两个位置上的数>=2
首先将[a,b]分解为[1,b]-[1,a-1]
然后令f[i][j]为以i开头的j位windy数有多少个
然后十进制拆分即可
此题有些要讨论的地方:
1.小心爆int
2.最后一位要单独讨论
3.已经确定的数字是否不满足windy数的条件
4.一开始的[0,99...99]的区间需要单独计算
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int f[10][20];//f[i][j]表示以i开头的j位windy数有多少
bool Conflict(int x)
{
int temp=-10;
while(x)
{
if(abs(temp-x%10)<2)
return true;
temp=x%10;x/=10;
}
return false;
}
int Digital_DP(ll x)
{
int i,j,re=0;
ll pos,now;
for(i=1,pos=10;pos<=x;i++,pos*=10)
{
for(j=1;j<=9;j++)
re+=f[j][i];
}
now=pos/=10;--i;
while(now<x)
{
while(now+pos<=x)
{
int temp=now/pos%10;
if( !Conflict(now/pos) )
for(j=0;j<=9;j++)
if(abs(j-temp)>=2||pos==1)
re+=f[j][i];
now+=pos;
}
if( Conflict(now/pos) )
break;
pos/=10;--i;
}
return re;
}
int main()
{
int i,j,k;
f[0][0]=1;
for(i=0;i<=9;i++)
f[i][1]=1;
for(j=2;j<=10;j++)
for(i=0;i<=9;i++)
for(k=0;k<=9;k++)
if(abs(i-k)>=2)
f[i][j]+=f[k][j-1];
int a,b;
cin>>a>>b;
cout<<Digital_DP(b+1)-Digital_DP(a)<<endl;
}