📌  相关文章
📜  查询计数范围为[L,R]的整数,以使它们的数字和为质数且可被K整除

📅  最后修改于: 2021-06-26 01:42:57             🧑  作者: Mango

给定Q个查询和一个整数K ,其中每个查询由一个范围[L,R]组成,任务是查找给定范围内的整数的计数,该整数的位数是素数且可被K整除。
例子:

Input: Q = { {1, 11},
      {5, 15},
      {2, 24} } 
K = 2
Output: 
2
1
3
Explanation:
Query 1: 2 and 11 are the only 
numbers in the given range whose 
digit sum is prime and divisible by K.
Query 2: 11 is the only number.
Query 3: 2, 11 and 20.

Input: Q = { {2, 17},
             {3, 24} }
K = 3
Output:
2
3

方法:

  • 首先使用Eratosthenes的Sieve预先计算所有素数,直到所有给定范围内R的最大可能值,即maxVal
  • 然后标记从1maxVal的所有整数,这些整数可以被K整除并且是素数。
  • 取标记数组的前缀和。
  • 通过prefix [right] – prefix [left – 1]回答给定的查询。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
const int maxSize = 1e5 + 1;
bool isPrime[maxSize];
int prefix[maxSize];
 
// Function to return the
// digit sum of num
int digitSum(int num)
{
    int s = 0;
    while (num != 0) {
        s = s + num % 10;
        num = num / 10;
    }
    return s;
}
 
// Sieve Function to generate
// all primes opto maxSize
void sieveOfEratosthenes()
{
    for (int i = 2; i < maxSize; i++) {
        isPrime[i] = true;
    }
 
    for (int i = 2; i * i <= maxSize; i++) {
        if (isPrime[i]) {
            for (int j = i * i; j < maxSize; j += i) {
                isPrime[j] = false;
            }
        }
    }
}
 
// Pre-Computation till maxSize
// and for a given K
void precompute(int k)
{
    sieveOfEratosthenes();
    for (int i = 1; i < maxSize; i++) {
        // Getting Digit Sum
        int sum = digitSum(i);
        // Check if the digit sum
        // is prime and divisible by k
        if (isPrime[sum] == true && sum % k == 0) {
            prefix[i]++;
        }
    }
 
    // Taking Prefix Sum
    for (int i = 1; i < maxSize; i++) {
        prefix[i] = prefix[i] + prefix[i - 1];
    }
}
 
// Function to perform the queries
void performQueries(int k, int q,
                    vector >& query)
{
    // Precompute the results
    precompute(k);
 
    vector ans;
    for (int i = 0; i < q; i++) {
        int l = query[i][0], r = query[i][1];
 
        // Getting count of range in range [L, R]
        int cnt = prefix[r] - prefix[l - 1];
        cout << cnt << endl;
    }
}
 
// Driver code
int main()
{
    vector > query = { { 1, 11 },
                                   { 5, 15 },
                                   { 2, 24 } };
    int k = 2, q = query.size();
    performQueries(k, q, query);
 
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
    static final int maxSize = (int)1e5 + 1;
    static boolean isPrime[] = new boolean[maxSize];
    static int prefix[] = new int[maxSize];
     
    // Function to return the
    // digit sum of num
    static int digitSum(int num)
    {
        int s = 0;
        while (num != 0)
        {
            s = s + num % 10;
            num = num / 10;
        }
        return s;
    }
     
    // Sieve Function to generate
    // all primes opto maxSize
    static void sieveOfEratosthenes()
    {
        for (int i = 2; i < maxSize; i++)
        {
            isPrime[i] = true;
        }
     
        for (int i = 2; i * i <= maxSize; i++)
        {
            if (isPrime[i])
            {
                for (int j = i * i;
                         j < maxSize; j += i)
                {
                    isPrime[j] = false;
                }
            }
        }
    }
     
    // Pre-Computation till maxSize
    // and for a given K
    static void precompute(int k)
    {
        sieveOfEratosthenes();
         
        for (int i = 1; i < maxSize; i++)
        {
             
            // Getting Digit Sum
            int sum = digitSum(i);
             
            // Check if the digit sum
            // is prime and divisible by k
            if (isPrime[sum] == true &&
                        sum % k == 0)
            {
                prefix[i]++;
            }
        }
     
        // Taking Prefix Sum
        for (int i = 1; i < maxSize; i++)
        {
            prefix[i] = prefix[i] +
                        prefix[i - 1];
        }
    }
     
    // Function to perform the queries
    static void performQueries(int k, int q,
                               int query[][])
    {
        // Precompute the results
        precompute(k);
         
        for (int i = 0; i < q; i++)
        {
            int l = query[i][0], r = query[i][1];
     
            // Getting count of range in range [L, R]
            int cnt = prefix[r] - prefix[l - 1];
             
            System.out.println(cnt);
        }
    }
     
    // Driver code
    public static void main (String[] args)
    {
        int query[][] = { { 1, 11 },
                          { 5, 15 },
                          { 2, 24 } };
        int k = 2, q = query.length;
        performQueries(k, q, query);
    }
}
 
// This Code is contributed by AnkitRai01


Python3
# Python3 implementation of the approach
from math import sqrt
 
maxSize = 10 ** 5 + 1;
isPrime = [0] * maxSize;
prefix = [0] * maxSize;
 
# Function to return the
# digit sum of num
def digitSum(num) :
     
    s = 0;
    while (num != 0) :
        s = s + num % 10;
        num = num // 10;
 
    return s;
 
# Sieve Function to generate
# all primes opto maxSize
def sieveOfEratosthenes() :
 
    for i in range(2, maxSize) :
        isPrime[i] = True;
 
    for i in range(2, int(sqrt(maxSize)) + 1) :
        if (isPrime[i]) :
            for j in range(i * i, maxSize, i) :
                isPrime[j] = False;
         
# Pre-Computation till maxSize
# and for a given K
def precompute(k) :
 
    sieveOfEratosthenes();
     
    for i in range(1, maxSize) :
         
        # Getting Digit Sum
        sum = digitSum(i);
         
        # Check if the digit sum
        # is prime and divisible by k
        if (isPrime[sum] == True and
                    sum % k == 0) :
            prefix[i] += 1;
 
    # Taking Prefix Sum
    for i in range(1, maxSize) :
        prefix[i] = prefix[i] + prefix[i - 1];
 
# Function to perform the queries
def performQueries(k, q, query) :
 
    # Precompute the results
    precompute(k);
 
    for i in range(q) :
        l = query[i][0]; r = query[i][1];
 
        # Getting count of range in range [L, R]
        cnt = prefix[r] - prefix[l - 1];
        print(cnt);
         
# Driver code
if __name__ == "__main__" :
 
    query = [ [ 1, 11 ],
              [ 5, 15 ],
              [ 2, 24 ] ];
             
    k = 2; q = len(query);
    performQueries(k, q, query);
     
# This code is contributed by kanugargng


C#
// C# implementation of the above approach
using System;
     
class GFG
{
    static readonly int maxSize = (int)1e5 + 1;
    static Boolean []isPrime = new Boolean[maxSize];
    static int []prefix = new int[maxSize];
     
    // Function to return the
    // digit sum of num
    static int digitSum(int num)
    {
        int s = 0;
        while (num != 0)
        {
            s = s + num % 10;
            num = num / 10;
        }
        return s;
    }
     
    // Sieve Function to generate
    // all primes opto maxSize
    static void sieveOfEratosthenes()
    {
        for (int i = 2; i < maxSize; i++)
        {
            isPrime[i] = true;
        }
     
        for (int i = 2; i * i <= maxSize; i++)
        {
            if (isPrime[i])
            {
                for (int j = i * i;
                         j < maxSize; j += i)
                {
                    isPrime[j] = false;
                }
            }
        }
    }
     
    // Pre-Computation till maxSize
    // and for a given K
    static void precompute(int k)
    {
        sieveOfEratosthenes();
         
        for (int i = 1; i < maxSize; i++)
        {
             
            // Getting Digit Sum
            int sum = digitSum(i);
             
            // Check if the digit sum
            // is prime and divisible by k
            if (isPrime[sum] == true &&
                        sum % k == 0)
            {
                prefix[i]++;
            }
        }
     
        // Taking Prefix Sum
        for (int i = 1; i < maxSize; i++)
        {
            prefix[i] = prefix[i] +
                        prefix[i - 1];
        }
    }
     
    // Function to perform the queries
    static void performQueries(int k, int q,
                               int [,]query)
    {
        // Precompute the results
        precompute(k);
         
        for (int i = 0; i < q; i++)
        {
            int l = query[i, 0], r = query[i, 1];
     
            // Getting count of range in range [L, R]
            int cnt = prefix[r] - prefix[l - 1];
             
            Console.WriteLine(cnt);
        }
    }
     
    // Driver code
    public static void Main (String[] args)
    {
        int [,]query = {{ 1, 11 },
                        { 5, 15 },
                        { 2, 24 }};
        int k = 2, q = query.GetLength(0);
        performQueries(k, q, query);
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript


输出:
2
1
3

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。