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,99] 中
- 每个数位有序排列呈等差数列
简而言之,形如 13579、2468、6666 的数均符合条件,在题干所给数据范围内符合条件的数的个数并不多,而且此类数存在一定规律,故可以直接构造(一位数一位数构造)。
构造算法大致如下:
- 从 1 到 9 依次取一个数作为 ADA IV 型数的起始位
- 从 -9 到 9 依次取一个数作为构造时的 公差
- 构造一位数以后将这一位添加到 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);
}
}
注:
- qsort 函数依赖于头文件 stdlib.h
- 预处理部分构造使用数据类型 long long (_int64) 目的是防止 运算溢出 造成判定错误
- 变量 i 即起始的数位,变量 dif 即公差,变量 b 即构造后需要添加到 ADA IV 型数后面的数位,变量 res 即构造后的 ADA IV 型数
- 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;
}
}
注:
- 写法与 C 语言实现 代码大同小异
- sort 函数依赖于头文件 algorithm,注意,使用方法与 qsort 不同
以上。