傳送門
描述
杭州人稱那些傻乎乎粘嗒嗒的人爲 62(音:laoer)。
杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大衆。
不吉利的數字爲所有含有 4 或 62 的號碼。例如:62315,73418,88914 都屬於不吉利號碼。但是,61152 雖然含有 6 和 2,但不是 連號,所以不屬於不吉利數字之列。
你的任務是,對於每次給出的一個牌照號區間 [n,m],推斷出交管局今後又要實際上給多少輛新的士車上牌照了。
輸入格式
輸入包含多組測試數據,每組數據佔一行。
每組數據包含一個整數對 n 和 m。
當輸入一行爲“0 0”時,表示輸入結束。
輸出格式
對於每個整數對,輸出一個不含有不吉利數字的統計個數,該數值佔一行位置。
數據範圍
1≤n≤m≤107
輸入樣例:
1 100
0 0
輸出樣例:
80
這題是經典的數位dp,對於包含4和62就是壞的數字
我們首先計算數字的位數和每一位上的數存起來,因爲我們需要控制上限
然後通過深搜來遍歷每一位,然後搜索的時候記憶化一下
AC代碼如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[8][2],digit[8]; //dp[i][state]表示當前是第i位數字,state表示前面一位是否爲6
int dfs(int len,bool state,bool up) { //len表示我們當前的長度,state表示上一位是否爲6,up表示上一位是否達到上限
if(!len) return 1;
if(!up&&dp[len][state]!=-1) return dp[len][state];
int ret=0,upmax=up?digit[len]:9; //如果上一位到達上限,則這一位上限是digit[len],否則爲9
for(int i=0;i<=upmax;i++){
if(i==4||state&&i==2) continue;
ret+=dfs(len-1,i==6,up&&i==upmax);
}
if(!up) dp[len][state]=ret; //上一位沒達到上限表示這個結果是可以通用的,
return ret;
}
int f(int n) {
int len = 0;
while(n) {
digit[++len] = n % 10;
n /= 10;
}
return dfs(len,false,true);
}
int main() {
int a,b;
memset(dp,-1,sizeof(dp));
while(scanf("%d%d",&a,&b),a||b) {
printf("%d\n",f(b)-f(a-1));
}
return 0;
}