#10164. 「一本通 5.3 例 2」数字游戏

题目描述】题目

科协里最近很流行数字游戏。某人命名了一种不降数,这种数字必须满足从左到右各位数字成小于等于的关系,如 123,446。现在大家决定玩一个游戏,指定一个整数闭区间 [a,b],问这个区间内有多少个不降数。

输入格式

有多组测试数据。每组只含两个数字 a,b意义如题目描述。

输出格式

每行给出一个测试数据的答案,即 [a,b]之间有多少不降数。

样例输入

1 9
1 19

样例输出

9
18

数据范围与提示

对于全部数据,1≤a≤b≤231−11\le a\le b\le 2^{31}-11≤a≤b≤2​31​​−1。

 

思路:这道题虽然是例2,但是我感觉例1要难一点,这一题就是一位位去寻找,去排除答案,然后预处理f就是寻找数位。然后最后的x~y的范围的答案就是 (0~y)的答案数-(0~x)的答案数,就是最后的答案数。具体代码的解释我写的已经很清楚的,找x范围的答案和找y范围的答案的做法是一模一样的,这道题理解清楚就不难,但一定要找清楚数位之间的关系,然后要从最高位开始枚举。

【代码实现】

#include
#include
#include
using namespace std;
int f[110][110];//f[i][j]代表以i开头的j位非降序数有多少个 
int a[110],b[110],alen,blen;//alen表示x范围的位数,blen表示y范围的位数,a[i]表示存储x范围这一个位数,b[i]表示存储y范围这一个位数 
void dfs()//预处理f 
{
	for(int i=1;i<=9;i++) f[i][1]=1;//一位数的情况,1~9肯定是非降序数 
	for(int i=2;i<=10;i++)//表示从第二位数开始循环 
	{
		for(int j=0;j<=9;j++)//表示j位数的最高位 
		{
			for(int k=j;k<=9;k++) f[j][i]+=f[k][i-1];//因为要比前一个大,所以k要从j开始循环//枚举次高位,然后加上去 
		}
	}
}
int main()
{	
	dfs();//先预处理 
	long long x,y,sum1,sum2;
	while(scanf("%lld%lld",&x,&y)!=EOF)//有多组数据 
	{
		x--;//先将范围减少一个 
		alen=0; blen=0;//初始化 
		while(x>0)//范围等于0的时候就不存在成立的数 
		{
			a[++alen]=x%10;
			x/=10;
		}//这一步就是分出每一位 //把x的每一位分出来放到a数组里面 
		sum1=0;//初始化 
		a[alen+1]=0;//第一位为0 
		for(int i=alen;i>=1;i--)//从最高位开始循环 
		//声明一点:这里是找严格比x小的数 
		{
			//首先我们找的这一位是在前面位数确定下来的情况下,前i+1位都已经找到a[i+1]上了,(0-4789,我们已经找到47,继续找十位这样) 
			if(a[i]0)//范围等于0的时候就不存在成立的数
		{
			b[++blen]=y%10;
			y/=10;
		}//这一步就是分出每一位 //把y的每一位分出来放到b数组里面
		sum2=0;//初始化 
		b[blen+1]=0;//第一位为0
		for(int i=blen;i>=1;i--)//从最高位开始循环
		//声明一点:这里是找严格比y小的数 
		{
			//首先我们找的这一位是在前面位数确定下来的情况下,前i+1位都已经找到b[i+1]上了,(0-4789,我们已经找到47,继续找十位这样)
			if(b[i]

难度系数为6。加油!!!

你可能感兴趣的:(LOJ)