AcWing 1085 不要62
作者:互联网
题目描述:
杭州人称那些傻乎乎粘嗒嗒的人为 62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有 4 或 62 的号码。例如:62315,73418,88914 都属于不吉利号码。但是,61152 虽然含有 6 和 2,但不是 连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照号区间 [n,m],推断出交管局今后又要实际上给多少辆新的士车上牌照了。
输入格式
输入包含多组测试数据,每组数据占一行。
每组数据包含一个整数对 n 和 m。
当输入一行为“0 0”时,表示输入结束。
输出格式
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
数据范围
1≤n≤m≤10^9
输入样例:
1 100
0 0
输出样例:
80
分析:
方法一:动态规划
本题同样是相当简单的数位DP问题,f[i][j]表示以j为开头的i位数中不含4和62数的个数。状态转移方程为f[i][j] += f[i-1][k],其中j != 4,k != 4,j等于6时k不能等于2。枚举每一位时,需要注意的是当n的当前位置数是4或者前面的一位是6,当前位是2时需要终止枚举。
#include <iostream>
#include <vector>
using namespace std;
const int N = 12;
int f[N][N];
void init(){
for(int i = 0;i <= 9;i++) f[1][i] = (i != 4);
for(int i = 2;i < N;i++){
for(int j = 0;j <= 9;j++){
if(j == 4) continue;
for(int k = 0;k <= 9;k++){
if(k!=4 && !(j==6&&k==2)) f[i][j] += f[i-1][k];
}
}
}
}
int get(int n){
if(!n) return 1;
vector<int> num;
while(n) num.push_back(n % 10),n /= 10;
int res = 0,last = 0;
for(int i = num.size() - 1;i >= 0;i--){
int x = num[i];
for(int j = 0;j < x;j++){
if(j!=4 && !(last==6&&j==2)) res += f[i + 1][j];
}
if(x == 4 || (last == 6 && x==2)) break;
if(!i) res++;
last = x;
}
return res;
}
int main(){
int n,m;
init();
while(cin>>n>>m,n || m){
cout<<get(m) - get(n-1)<<endl;
}
return 0;
}
方法二:记忆化搜索
本题的记忆化搜索也只用在上一题的dfs框架中略加修改即可实现功能。dfs的参数有u,pre以及flag,当当前枚举到的数是4或者当前枚举到的数是2并且上一位是6时就跳过即可。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 12;
int len,num[N],f[N][100][2];
int dfs(int u,int pre,int flag){
if(f[u][pre][flag] != -1) return f[u][pre][flag];
if(!u) return 1;
int res = 0;
for(int i = 0;i <= 9;i++){
if(i == 4 || (pre==6 && i == 2)) continue;
if(flag && i >= num[u]){
if(i == num[u]) res += dfs(u - 1,i,1);
break;
}
else res += dfs(u - 1,i,0);
}
return f[u][pre][flag] = res;
}
int get(int n){
if(!n) return 1;
len = 0;
while(n) num[++len] = n % 10,n /= 10;
memset(f,-1,sizeof f);
return dfs(len,0,1);
}
int main(){
int a,b;
while(cin>>a>>b,a || b){
cout<<get(b) - get(a - 1)<<endl;
}
return 0;
}
昂昂累世士 发布了311 篇原创文章 · 获赞 31 · 访问量 1万+ 私信 关注
标签:1085,return,int,res,flag,dfs,62,num,AcWing 来源: https://blog.csdn.net/qq_30277239/article/details/104502932