简单数位dp
dp【i】【t】记录长度为i位首位为t的满足题意的数字个数,dp时很简单,如果首位为6则次位不能为2,若首位为4则直接等于0。
统计时注意高位部分若含有62或4则直接跳出,在此之前统计的结果作为结果,否则继续统计。
#include <iostream>
#include <cstring>
using namespace std;
int dp[10][10];
int main()
{
for (int i=0;i<=9;i++)
dp[1][i]=1;
for (int i=2;i<=7;i++)
{
for (int t=0;t<=9;t++)
{
for (int k=0;k<=9;k++)
{
if (t==4||k==4)
continue;
if (t!=6||k!=2)
{
dp[i][t]+=dp[i-1][k];
}
}
}
}
int l,r;
while (cin>>l>>r&&(l+r))
{
int d1[10];
int d2[10];
memset(d1,0,sizeof(d1));
memset(d2,0,sizeof(d2));
int len1=1;
int len2=1;
while (l>0)
{
d1[len1]=l%10;
l=l/10;
len1++;
}
while (r>0)
{
d2[len2]=r%10;
r=r/10;
len2++;
}
int sum1=0;
int sum2=0;
for (int i=len1-1;i>=1;i--)
{
for (int t=0;t<d1[i];t++)
{
if ((t==2&&d1[i+1]==6)||t==4)
continue;
sum1=sum1+dp[i][t];
}
if (d1[i]==4||(d1[i+1]*10+d1[i])==62)
break;
}
for (int i=len2-1;i>=1;i--)
{
for (int t=0;t<d2[i];t++)
{
if ((t==2&&d2[i+1]==6)||t==4)
continue;
sum2=sum2+dp[i][t];
//cout<<i<<" "<<t<<" "<<dp[i][t]<<endl;
}
if (i==1&&d2[i]!=4&&(d2[i+1]*10+d2[i])!=62)
sum2++;
if (d2[i]==4||(d2[i+1]*10+d2[i])==62)
break;
}
//cout<<sum1<<" "<<sum2<<endl;
cout<<sum2-sum1<<endl;
}
return 0;
}