Problem 2109 Mountain Number
Accept: 139 Submit: 357
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
31 101 1001 1000
Sample Output
954384
这题要求统计出【l,r】这个区间内 山数的总数。
山数就是奇数位不小于左右两边的数 的数 如 1919191 45454 1111 这三个都是山数
写了个函数 san(int) 来计算0-n中
#include <stdio.h>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cctype>
#include <cmath>
#include <string.h>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
int dp[15][15];//两维 分别表示位数 和 digit digit=10代表这个位上最大的数
int san(int n)
{
if(n==0)
return 1;
int tem=n;
int l=0;
int ji[15];
for(int i=0;tem;i++)
{
ji[l++]=tem%10;
tem/=10;
}
for(int i=0;i<l/2;i++)//ji数组存各个位上的digit
{
swap(ji[i],ji[l-1-i]);
}
if(l==1)
return ji[0]+1;
memset(dp,0,sizeof dp);
for(int i=1;i<ji[0];i++)
{
dp[0][i]=1;
}
dp[0][10]=1;
int jo=1;
for(int i=1;i<l;i++)
{
if(ji[i]>=ji[i-1]&&jo==1)//前一个最大数 转移 当前位最大数
dp[i][10]=dp[i-1][10];
else if(ji[i]<=ji[i-1]&&jo==0)
dp[i][10]=dp[i-1][10];
if(jo==0)//前一个最大数 转移 当前位其他数字
for(int j=0;j<=ji[i-1]&&j<ji[i];j++)
{
dp[i][j]+=dp[i-1][10];
}
if(jo==1)
for(int j=ji[i-1];j<ji[i];j++)
{
dp[i][j]+=dp[i-1][10];
}
for(int j=0;j<=9;j++)//前一个数位 转移 当前位其他数字
{
if(jo==1)
for(int k=0;k<=j;k++)
{
dp[i][j]+=dp[i-1][k];
}
if(jo==0)
for(int k=j;k<=9;k++)
{
dp[i][j]+=dp[i-1][k];
}
}
jo^=1;
}
int ans=0;
for(int i=0;i<=10;i++)
{
ans+=dp[l-1][i];
}
int zong=0;
l--;//因为前导零不算 所以假设 所以还要计算剩下 0-99999
while(l--)
{
zong*=10;
zong+=9;
}
return ans+san(zong);
}
int main()
{
int t,n,l,r;
scanf("%d",&t);
while(t--)
{
//scanf("%d",&l);
//printf("%d\n",san(l));
scanf("%d%d",&l,&r);
printf("%d\n",san(r)-san(l-1));
}
return 0;
}