给定一个由N个形式为{L,R}的查询组成的数组Q [] [] ,每个查询的任务是从范围[L,R]中找到可以被以下各项之和整除的总数他们的数字。
例子:
Input: Q[][]= {{5, 9}, {5, 20}}
Output:
5
9
Explanation:
Query 1: The numbers in the range [5, 9] which are divisible by the sum of their digits are {5, 6, 7, 8, 9}.
Query 2: The numbers in the range [5, 20] which are divisible by the sum of their digits are {5, 6, 7, 8, 9, 10, 12, 18, 20}.
Input: Q[][] = {{1, 30}, {13, 15}}
Output:
17
0
Explanation:
Query 1: The numbers in the range [5, 9] which are divisible by the sum of their digits are {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 18, 20, 21, 24, 27, 30}.
Query 2: No such number exists in the range [13, 15].
方法:可以使用包含-排除原理和前缀和数组技术来解决该问题。
请按照以下步骤解决给定的问题:
- 初始化一个数组arr []以存储在每个第i个索引处,该数目最多可被i位数除以i的数字。
- 使用变量i遍历[ 1,10 5 ]的范围,并针对每个第i个元素,检查i是否可被其位数之和整除。
- 如果发现为真,则设置arr [i] = 1 。
- 否则,设置arr [i] = 0 。
- 将数组arr []修改为其前缀和数组。
- 遍历数组Q [] [] ,对于每个查询,从[L,R]范围内计算所需数字的总计数,该范围等于arr [R] – arr [L – 1] 。
下面是上述方法的实现:
C++
// C++ program of the
// above approach
#include
using namespace std;
int arr[100005];
// Function to check if the number x
// is divisible by its sum of digits
bool isDivisible(int x)
{
// Stores sum of digits of x
int sum = 0;
// Temporarily store x
int temp = x;
// Calculate sum
// of digits of x
while (x != 0) {
sum += x % 10;
x /= 10;
}
// If x is not divisible by sum
if (temp % sum)
return false;
// Otherwise
else
return true;
}
// Function to perform
// the precomputation
void precompute()
{
// Iterate from i equals 1 to 1e5
for (int i = 1; i <= 100000; i++) {
// Check if i is divisible
// by sum of its digits
if (isDivisible(i))
arr[i] = 1;
else
arr[i] = 0;
}
// Convert arr[] to prefix sum array
for (int i = 1; i <= 100000; i++) {
arr[i] = arr[i] + arr[i - 1];
}
}
// Driver code
int main()
{
// Given queries
vector > Q = { { 5, 9 }, { 5, 20 } };
precompute();
for (auto it : Q) {
// Using inclusion-exclusion
// principle, calculate the result
cout << arr[it.second] - arr[it.first - 1] << "\n";
}
return 0;
}
Java
// java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
static int arr[] = new int[100005];
// Function to check if the number x
// is divisible by its sum of digits
static boolean isDivisible(int x)
{
// Stores sum of digits of x
int sum = 0;
// Temporarily store x
int temp = x;
// Calculate sum
// of digits of x
while (x != 0) {
sum += x % 10;
x /= 10;
}
// If x is not divisible by sum
if (temp % sum != 0)
return false;
// Otherwise
else
return true;
}
// Function to perform
// the precomputation
static void precompute()
{
// Iterate from i equals 1 to 1e5
for (int i = 1; i <= 100000; i++) {
// Check if i is divisible
// by sum of its digits
if (isDivisible(i))
arr[i] = 1;
else
arr[i] = 0;
}
// Convert arr[] to prefix sum array
for (int i = 1; i <= 100000; i++) {
arr[i] = arr[i] + arr[i - 1];
}
}
// Driver Code
public static void main(String[] args)
{
// Given queries
int Q[][] = { { 5, 9 }, { 5, 20 } };
precompute();
for (int q[] : Q) {
// Using inclusion-exclusion
// principle, calculate the result
System.out.println(arr[q[1]] - arr[q[0] - 1]);
}
}
}
5
9
时间复杂度: O(N)
辅助空间: O(maxm),其中maxm表示R的最大值。