📜  计算给定范围内的数字,可以表示为数字总和的数字计数次方

📅  最后修改于: 2021-09-04 11:44:18             🧑  作者: Mango

给定一个由 {L, R}形式的查询组成的数组 arr[] ,每个查询的任务是计算[L, R]范围内的数字,这些数字可以表示为其数字的乘方之和的位数。

例子:

朴素的方法:最简单的方法是为每个查询迭代 arr[i][0]arr[i][1]的范围并打印这些数字的计数。

时间复杂度: O(Q*(R – L)*log 10 R),其中 R 和 L 表示最长范围的限制。
辅助空间: O(1)

有效的方法:上述方法可以通过预先计算并存储所有数字来优化,无论它们是否可以表示为其数字之和的数字数次幂。最后,有效地打印每个查询的计数。
请按照以下步骤解决问题:

  • 初始化一个辅助数组,比如ans[] ,以存储在 ans[i] 中,i 是否可以表示为其数字的总和,以数字计数的幂。
  • 迭代范围[1, 10 6 ]并相应地更新数组ans[]
  • 将数组ans[]转换为前缀和数组。
  • 遍历给定的查询数组arr[]并且对于每个查询{arr[i][0], arr[i][1]} ,打印(ans[arr[i][1]] – ans[arr [i][1] – 1])作为数字的结果计数,可以表示为其数字之和的数字计数次方。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
#define R 100005
int arr[R];
 
// Function to check if a number N can be
// expressed as sum of its digits raised
// to the power of the count of digits
bool canExpress(int N)
{
    int temp = N;
 
    // Stores the number of digits
    int n = 0;
 
    while (N != 0) {
        N /= 10;
        n++;
    }
 
    // Stores the resultant number
    N = temp;
 
    int sum = 0;
 
    while (N != 0) {
        sum += pow(N % 10, n);
        N /= 10;
    }
 
    // Return true if both the
    // numbers are same
    return (sum == temp);
}
 
// Function to precompute and store
// for all numbers whether they can
// be expressed
void precompute()
{
    // Mark all the index which
    // are plus perfect number
    for (int i = 1; i < R; i++) {
 
        // If true, then update the
        // value at this index
        if (canExpress(i)) {
            arr[i] = 1;
        }
    }
 
    // Compute prefix sum of the array
    for (int i = 1; i < R; i++) {
        arr[i] += arr[i - 1];
    }
}
 
// Function to count array elements that
// can be expressed as the sum of digits
// raised to the power of count of digits
void countNumbers(int queries[][2], int N)
{
    // Precompute the results
    precompute();
 
    // Traverse the queries
    for (int i = 0; i < N; i++) {
 
        int L1 = queries[i][0];
        int R1 = queries[i][1];
 
        // Print the resultant count
        cout << (arr[R1] - arr[L1 - 1])
             << ' ';
    }
}
 
// Driver Code
int main()
{
    int queries[][2] = {
        { 1, 400 },
        { 1, 9 }
    };
    int N = sizeof(queries)
            / sizeof(queries[0]);
    countNumbers(queries, N);
 
    return 0;
}


C#
// C# program for the above approach
using System;
 
class GFG{
     
static int R = 100005;
static int[] arr = new int[R];
 
// Function to check if a number N can be
// expressed as sum of its digits raised
// to the power of the count of digits
public static bool canExpress(int N)
{
    int temp = N;
 
    // Stores the number of digits
    int n = 0;
 
    while (N != 0)
    {
        N /= 10;
        n++;
    }
 
    // Stores the resultant number
    N = temp;
 
    int sum = 0;
 
    while (N != 0)
    {
        sum += ((int)Math.Pow(N % 10, n));
        N /= 10;
    }
 
    // Return true if both the
    // numbers are same
      if (sum == temp)
      return true;
   
    return false;
}
 
// Function to precompute and store
// for all numbers whether they can
// be expressed
public static void precompute()
{
 
    // Mark all the index which
    // are plus perfect number
    for(int i = 1; i < R; i++)
    {
         
        // If true, then update the
        // value at this index
        if (canExpress(i))
        {
            arr[i] = 1;
        }
    }
 
    // Compute prefix sum of the array
    for(int i = 1; i < R; i++)
    {
        arr[i] += arr[i - 1];
    }
}
 
// Function to count array elements that
// can be expressed as the sum of digits
// raised to the power of count of digits
public static void countNumbers(int[,] queries, int N)
{
     
    // Precompute the results
    precompute();
 
    // Traverse the queries
    for(int i = 0; i < N; i++)
    {
        int L1 = queries[i, 0];
        int R1 = queries[i, 1];
 
        // Print the resultant count
        Console.Write((arr[R1] - arr[L1 - 1]) + " ");
    }
}
 
// Driver Code
static public void Main()
{
    int[,] queries = { { 1, 400 }, { 1, 9 } };
    int N = queries.GetLength(0);
 
    // Function call
    countNumbers(queries, N);
}
}
 
// This code is contributed by Dharanendra L V.


Python3
# Python 3 program for the above approach
R = 100005
arr = [0 for i in range(R)]
 
# Function to check if a number N can be
# expressed as sum of its digits raised
# to the power of the count of digits
def canExpress(N):
    temp = N
 
    # Stores the number of digits
    n = 0
    while (N != 0):
        N //= 10
        n += 1
 
    # Stores the resultant number
    N = temp
    sum = 0
    while (N != 0):
        sum += pow(N % 10, n)
        N //= 10
 
    # Return true if both the
    # numbers are same
    return (sum == temp)
 
# Function to precompute and store
# for all numbers whether they can
# be expressed
def precompute():
   
    # Mark all the index which
    # are plus perfect number
    for i in range(1, R, 1):
       
        # If true, then update the
        # value at this index
        if(canExpress(i)):
            arr[i] = 1
 
    # Compute prefix sum of the array
    for i in range(1,R,1):
        arr[i] += arr[i - 1]
 
# Function to count array elements that
# can be expressed as the sum of digits
# raised to the power of count of digits
def countNumbers(queries, N):
   
    # Precompute the results
    precompute()
 
    # Traverse the queries
    for i in range(N):
        L1 = queries[i][0]
        R1 = queries[i][1]
 
        # Print the resultant count
        print((arr[R1] - arr[L1 - 1]),end = " ")
 
# Driver Code
if __name__ == '__main__':
    queries = [[1, 400],[1, 9]]
    N = len(queries)
    countNumbers(queries, N)
 
    # This code is contributed by SURENDRA_GANGWAR.


Javascript


输出:
12 9

时间复杂度: O(Q + 10 6 )
辅助空间: O(10 6 )

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live