您的位置:首页 > 大数据 > 人工智能

FZU 2019 Mountain Number

2013-04-27 14:54 211 查看
Problem 2109 Mountain Number


Accept: 49 Submit: 120
Time Limit: 1000 mSec Memory Limit : 32768 KB



Problem Description

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

比如:7068 ,存于a数组a={8,6,0,7},那么第3位数就是7。
分析:dp[i][j][k]表示对于第i位,那么表示访问到第i位,此数还剩下i位。j表示第i-1位(即数字的下一位)填的数字,k=0表示当前为偶数位,否则为奇数位。
下面总结一下数位dp的通用写法:
关键在于写dfs,注意状态转移:
int dfs(int i,(其他参数),bool e){//i表示当前遍历第i位,e表示是否卡上界
if(i==-1)return (...);//遍历结束
if(!e&&dp[i][][]!=-1)return dp[i][][];//如果在不卡上界的情况下,dp[i][][]计算过,则直接返回,记忆化搜索
int res=0,u=e?a[i]:9,d;//确定上界
for(d=0;d<=u;d++){
res+=dfs(i-1,(状态转移后的参数),e&&d==u);
}
return e?res:dp[i][][]=res;
}


至于cal(int n){}就不用说明了
主函数写法:
int main(){
int T,l,r;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
while(T--){
scanf("%d%d",&l,&r);
printf("%d\n",cal(r)-cal(l-1));
}
return 0;
}

本题题意:询问区间[l,r]内“Mountain Number”数有多少个。Mountain
Number:指所有奇数位数字要大于等于和它相邻偶数位的数字
最后贴上本题代码:
注意本题中前导0的处理,当遍历到当前位置仍是前导0,则应把pre设为9
#include<cstdio>
#include<cstring>
int dp[12][10][2],a[12];
int dfs(int i,int pre,int parity,bool J,bool e){
if(i==-1)return 1;
if(!e&&dp[i][pre][parity]!=-1)return dp[i][pre][parity];
int res=0,u=e?a[i]:9,d;
for(d=0;d<=u;d++){
if(!(J||d))res+=dfs(i-1,9,0,0,e&&d==u);
else if(parity&&pre<=d)res+=dfs(i-1,d,!parity,J||d,e&&d==u);
else if(!parity&&pre>=d)res+=dfs(i-1,d,!parity,J||d,e&&d==u);
}
return e?res:dp[i][pre][parity]=res;
}
int cal(int n){
int i=0;
while(n){a[i++]=n%10,n/=10;}
return dfs(i-1,9,0,0,1);
}
int main(){ int T,l,r; scanf("%d",&T); memset(dp,-1,sizeof(dp)); while(T--){ scanf("%d%d",&l,&r); printf("%d\n",cal(r)-cal(l-1)); } return 0; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: