vj题目链接:https://cn.vjudge.net/problem/HDU-2089
HDU题目链接:acm.hdu.edu.cn/showproblem.php?pid=2089
借鉴博客:https://www.cnblogs.com/wenruo/p/4725005.html
递推写法:
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
int x,y,dp[15][15],d[15];
void init()
{
dp[0][0]=1;
for(int i=1; i<10; i++)
{
for(int j=0; j<10; j++)
{
for(int k=0; k<10; k++)
{
if(j!=4&&!(j==6&&k==2))
dp[i][j]+=dp[i-1][k];
}
}
}
}
int f(int x)
{
int len=0,ans=0;
while(x)
{
d[++len]=x%10;
x/=10;
}
d[len+1]=0;
for(int i=len; i>0; i--)
{
for(int j=0; j<d[i]; j++)
{
if(!(d[i+1]==6&&j==2))
{
ans+=dp[i][j];
}
}
if(d[i]==4||(d[i+1]==6&&d[i]==2))
break;
}
return ans;
}
int main()
{
init();
while(~scanf("%d%d",&x,&y),x||y)
{
printf("%d\n",f(y+1)-f(x));
}
}
递归写法:
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,m;
int w[15],dp[20][15];
int dfs(int pos,int pre,int lim)
{
if(pos==0) return 1;
if(!lim&&dp[pos][pre]!=-1) return dp[pos][pre];
int up=lim?w[pos]:9;
int ans=0;
for(int i=0;i<=up;i++)
{
if((pre==6&&i==2)||i==4)continue;
ans+=dfs(pos-1,i,lim&&i==w[pos]);
}
if(!lim) dp[pos][pre]=ans;
return ans;
}
int get(int x)
{
int pos=0;
while(x)
w[++pos]=x%10,x/=10;
return dfs(pos,0,1);
}
int main()
{
memset(dp,-1,sizeof(dp));
while(~scanf("%d%d",&n,&m),n||m)
{
printf("%d\n",get(m)-get(n-1));
}
}