這題沒考慮到前導0,就是不知道哪wa了,又補題一直wa,scanf和printf改成cin cout就對了 真不知道錯在哪了。。。剛剛又試了一下,G++scanf過不了 但是visual C++可以。真服了,浪費我又一個多小時。
這道題是簡單的數位dp!!!注意前導0!前導0!前導0!掉坑的地方說三遍,順便慶祝下因為前導0,成功爆0。
思路:就是數位dp模闆題,不過置前導0的時候要注意技巧,就是num要放9。為什麼放9呢?因為放9不會限制後面取數。暫且這麼記吧,我真沒整明白為啥放9嗚嗚嗚。
下面是AC代碼!一定要掌握前導0的處理!
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define maxn 20
using namespace std;//這題注意前導0!!!
int dig[maxn];
ll dp[maxn][maxn][2];
ll dfs(int pos,int num,int odd,int pre0,int limit){
if(!pos) return 1;
if(!limit&&dp[pos][num][odd]!=-1) return dp[pos][num][odd];
int up=limit?dig[pos]:9;
ll ans=0;
for(int i=0;i<=up;i++){
if(pre0==0&&i==0) ans+=dfs(pos-1,9,0,0,limit&&i==up);
else {
if(!odd&&i<=num) ans+=dfs(pos-1,i,!odd,pre0||i,limit&&i==up);
else if(odd&&i>=num) ans+=dfs(pos-1,i,!odd,pre0||i,limit&&i==up);
}
}
if(!limit) dp[pos][num][odd]=ans;
return ans;
}
ll solve(ll n){
int pos=0;
while(n){
dig[++pos]=n%10;
n/=10;
}
return dfs(pos,9,0,0,1);
}
int main(){
int T;
cin>>T;
memset(dp,-1,sizeof(dp));
while(T--){
ll l,r;
cin>>l>>r;
cout<<solve(r)-solve(l-1)<<endl;
}
return 0;
}
One integer number x is called “Mountain Number” if:
(1) x>0 and x is an integer;
(2) Assume x=a[0]a[1]…a[len-2]a[len-1](0≤a[i]≤9, a[0] is positive). Any a[2i+1] is larger or equal to a[2i] and a[2i+2](if exists).
For example, 111, 132, 893, 7 are “Mountain Number” while 123, 10, 76889 are not “Mountain Number”.
Now you are given L and R, how many “Mountain Number” can be found between L and R (inclusive) ?
Input
The first line of the input contains an integer T (T≤100), indicating the number of test cases.
Then T cases, for any case, only two integers L and R (1≤L≤R≤1,000,000,000).
Output
For each test case, output the number of “Mountain Number” between L and R in a single line.
Sample Input
3
1 10
1 100
1 1000
Sample Output
9
54
384