HNUST 1603 - ADA IV型数(打表)

ADA IV型数

1. 题目

题目描述

Ada三岁了,会掰着指头数数了.她的爸爸既是欢喜,又杂着忧愁.欢喜的是,教了她三年,终于会数了. 忧的是,Ada对数字实在不敏感啊!Ada的爸爸又准备了新的题目训练她.
ADA IV型数的定义如下: 把一个正整数的各个位上的数字依次组成一个数列,如果该数列是等差数列,则该数为ADA IV型数.如13579和2468都是ADA IV型数, 153和246810都不是ADA IV型数.为了避免不必要的麻烦,规定区间[1,99]的数均为ADA IV型数.
给定一个区间[A,B],其中1<=A<=B<=1000000000,问该区间含有多少个ADA IV型数.这个问题对ADA来说显然太难了,但是我想你行的,试一试吧.

输入

由多组测试数据组成, 组数不超过100。

每一组测试数据仅有一行,只包含由空格分开的整数A和B。

输出

对于每一组测试数据,输出对应区间的ADA IV型数的总数目,每组一行。

样例输入

1 100
112 160

样例输出

99
4

2. 分析

本题可抽象为求 [ 1, 1×10^9 ] 范围内的 ADA IV 型数,而 ADA IV 型数需满足如下条件之一:

  1. 在区间 [1,99] 中
  2. 每个数位有序排列呈等差数列

简而言之,形如 13579、2468、6666 的数均符合条件,在题干所给数据范围内符合条件的数的个数并不多,而且此类数存在一定规律,故可以直接构造(一位数一位数构造)。
 

构造算法大致如下:
  1. 从 1 到 9 依次取一个数作为 ADA IV 型数的起始位
  2. 从 -9 到 9 依次取一个数作为构造时的 公差
  3. 构造一位数以后将这一位添加到 ADA IV 型数的后面,并判断是否满足题干所给范围

3. 实现代码

C 语言实现

#include <stdio.h>
#include <stdlib.h>
int compare(const int* a, const int* b)
{
    return *a - *b;
}
int main()
{   // 预处理部分
    int data[257], index = 0;
    for (int i = 1; i <= 99; i++)
    {
        data[index++] = i;
    }
    typedef long long LL;
    for (LL i = 1; i < 10; i++)
    {
        for (LL dif = -9; dif < 10; dif++)
        {
            LL res = i;
            for (LL b = i + dif; b >= 0 && b < 10; b += dif)
            {
                res = res * 10 + b;
                if (res > 1000000000) break;
                else if (res > 100) data[index++] = (int)res;
            }
        }
    }
    // 预处理部分
    qsort(data + 99, 158, sizeof(int), compare);
 
    int A, B;
    while (~scanf("%d %d", &A, &B))
    {
        int cnt = 0;
        index = 0;
        while (index < 257)
        {
            if (data[index] >= A && data[index] <= B) cnt++;
            else if (data[index] > B) break;
            index++;
        }
        printf("%d\n", cnt);
    }
}

注:

  1. qsort 函数依赖于头文件 stdlib.h
  2. 预处理部分构造使用数据类型 long long (_int64) 目的是防止 运算溢出 造成判定错误
  3. 变量 i 即起始的数位,变量 dif 即公差,变量 b 即构造后需要添加到 ADA IV 型数后面的数位,变量 res 即构造后的 ADA IV 型数
  4. 257 这个结果数可以在自己尝试打表时增加一个计数变量得出

C++ 实现

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{   // 预处理部分
    int data[257], index = 0;
    for (int i = 1; i <= 99; i++)
    {
        data[index++] = i;
    }
    typedef long long LL;
    for (LL i = 1; i < 10; i++)
    {
        for (LL dif = -9; dif < 10; dif++)
        {
            LL res = i;
            for (LL b = i + dif; b >= 0 && b < 10; b += dif)
            {
                res = res * 10 + b;
                if (res > 1000000000) break;
                else if (res > 100) data[index++] = (int)res;
            }
        }
    }
    // 预处理部分
    sort(data + 99, data + 257);
 
    int A, B;
    while (cin >> A >> B)
    {
        int cnt = 0;
        index = 0;
        while (index < 257)
        {
            if (data[index] >= A && data[index] <= B) cnt++;
            else if (data[index] > B) break;
            index++;
        }
        cout << cnt << endl;
    }
}

注:

  1. 写法与 C 语言实现 代码大同小异
  2. sort 函数依赖于头文件 algorithm,注意,使用方法与 qsort 不同
     

以上。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值