这题没考虑到前导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