📜  查询给定范围内的数字,这些数字可被其数字之和整除

📅  最后修改于: 2021-04-17 19:18:41             🧑  作者: Mango

给定一个由N个形式为{L,R}的查询组成的数组Q [] [] ,每个查询的任务是从范围[L,R]中找到可以被以下各项之和整除的总数他们的数字。

例子:

方法:可以使用包含-排除原理和前缀和数组技术来解决该问题。
请按照以下步骤解决给定的问题:

  1. 初始化一个数组arr []以存储在每个i索引处,该数目最多可被i位数除以i的数字。
  2. 使用变量i遍历[ 1,10 5 ]的范围,并针对每个i元素,检查i是否可被其位数之和整除。
    • 如果发现为真,则设置arr [i] = 1
    • 否则,设置arr [i] = 0
  3. 将数组arr []修改为其前缀和数组。
  4. 遍历数组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的最大值。