📜  给定范围内的数字计数,可以表示为加和后的数字乘以数字的乘方

📅  最后修改于: 2021-04-17 15:46:24             🧑  作者: 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 )