HDU2089
题解
代码(无前导0)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int const N = 10;
int n,m,dp[N][N],a[N];
int dfs(int pos,int pre,int sta,int limit){
if(pos == 0) return 1;
if(!limit && dp[pos][sta] != -1) return dp[pos][sta];
int up = limit ? a[pos] : 9;
int tmp = 0;
for(int i=0;i<=up;i++){
if(pre == 6 && i == 2) continue;
if(i == 4) continue;
tmp += dfs(pos-1,i,i == 6,limit && i == a[pos]);
}
if(!limit) dp[pos][sta] = tmp;
return tmp;
}
int solve(int n){
int pos = 0;
while(n){
a[++pos] = n % 10;
n /= 10;
}
return dfs(pos,-1,0,1);
}
int main(){
while(~scanf("%d%d",&n,&m) && (n || m)){
memset(dp,-1,sizeof(dp));
cout<<solve(m) - solve(n-1)<<endl;
}
return 0;
}
luogu2657
代码(有前导0)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int const N = 20;
ll l,r,dp[N][N];
int a[N];
ll dfs(int pos,int pre,int sta,int limit){ //sta表示是否有前导0
if(pos == 0) return !sta; //存在前导0返回0
if(!limit && !sta && dp[pos][pre] != -1) return dp[pos][pre];
int up = limit ? a[pos] : 9;
int tmp = 0;
for(int i=0;i<=up;i++){
int delta = abs(i - pre);
if(!sta && delta >= 2) tmp += dfs(pos-1,i,sta,limit && i == a[pos]); //不存在前导0,后一位数有限制
else if(sta) tmp += dfs(pos-1,i,i == 0,limit && i == a[pos]); //存在前导0或者绝对值差<2,所以后一位数无限制
}
if(!limit && !sta) dp[pos][pre] = tmp; //无限制或者无前导0
return tmp;
}
ll solve(ll n){
int pos = 0;
while(n){
a[++pos] = n % 10;
n /= 10;
}
return dfs(pos,0,1,1);
}
int main(){
cin>>l>>r;
memset(dp,-1,sizeof(dp));
cout<<solve(r) - solve(l-1)<<endl;
return 0;
}