📜  具有给定的数字总和和数字平方和的最小数字

📅  最后修改于: 2021-04-23 21:03:25             🧑  作者: Mango

给定数字总和a和数字的平方和b 。查找具有给定数字总和和数字平方和的最小数字。该数字不能超过100位数字。如果不存在这样的数字或位数大于100,则打印-1。

例子:

方法:
由于最小的数字可以是100位数字,因此无法存储。因此,解决该问题的第一步将是找到最小的位数,该位数可以使我们得出位数的总和为a和数字平方的总和为b 。要找到最小位数,我们可以使用动态编程。 DP [a] [b]表示一个数字的最小位数,该数字的总和为a和数字的平方和将是b 。如果不存在任何这样的数字,则DP [a] [b]将为-1。

由于该数字不能超过100位,因此DP阵列的大小为101 * 8101 。迭代每个数字,然后尝试所有可能的数字组合,这将使我们得出的数字总和为a和数字平方的总和为b 。使用以下重复关系将最小位数存储在DP [a] [b]中:

获得最小位数后,找到数字。要查找数字,请检查所有组合并打印满足以下条件的数字:

如果i满足上述条件,则减小a通过我和b由我和我打破。继续重复上述过程以查找所有数字,直到a是0并且b是0。

下面是上述方法的实现:

C++
// CPP program to find the Smallest number 
// with given sum of digits and
// sum of square of digits
#include 
using namespace std;
  
int dp[901][8101];
  
// Top down dp to find minimum number of digits with
// given sum of dits a and sum of square of digits as b
int minimumNumberOfDigits(int a, int b)
{
    // Invalid condition 
    if (a > b || a < 0 || b < 0 || a > 900 || b > 8100)
        return -1;
      
    // Number of digits satisfied
    if (a == 0 && b == 0)
        return 0;
      
    // Memoization
    if (dp[a][b] != -1)
        return dp[a][b];
      
    // Initialize ans as maximum as we have to find the  
    // minimum number of digits 
    int ans = 101; 
      
    // Check for all possible combinations of digits
    for (int i = 9; i >= 1; i--) {
          
        // recurrence call 
        int k = minimumNumberOfDigits(a - i, b - (i * i)); 
          
        // If the combination of digits cannot give sum as a 
        // and sum of square of digits as b 
        if (k != -1)
            ans = min(ans, k + 1);
    }
      
    // Returns the minimum number of digits
    return dp[a][b] = ans;
}
  
// Function to print the digits that gives 
// sum as a and sum of square of digits as b
void printSmallestNumber(int a,int b)
{
      
    // initialize the dp array as -1
    memset(dp, -1, sizeof(dp));
      
    // base condition 
    dp[0][0] = 0;
      
    // function call to get the minimum number of digits  
    int k = minimumNumberOfDigits(a, b); 
      
    // When there does not exists any number
    if (k == -1 || k > 100)
        cout << "-1";
    else {
        // Printing the digits from the most significant digit
        while (a > 0 && b > 0) {
  
            // Trying all combinations 
            for (int i = 1; i <= 9; i++) {
                // checking conditions for minimum digits
                if (a >= i && b >= i * i && 
                    1 + dp[a - i][b - i * i] == dp[a][b]) {
                    cout << i;
                    a -= i;
                    b -= i * i;
                    break;
                }
            }
        }
    }
}
  
// Driver Code
int main()
{
    int a = 18, b = 162;
    // Function call to print the smallest number 
    printSmallestNumber(a,b); 
}


Java
import java.util.Arrays;
  
// Java program to find the Smallest number 
// with given sum of digits and
// sum of square of digits
class GFG {
  
    static int dp[][] = new int[901][8101];
  
// Top down dp to find minimum number of digits with
// given sum of dits a and sum of square of digits as b
    static int minimumNumberOfDigits(int a, int b) {
        // Invalid condition 
        if (a > b || a < 0 || b < 0 || a > 900 || b > 8100) {
            return -1;
        }
  
        // Number of digits satisfied
        if (a == 0 && b == 0) {
            return 0;
        }
  
        // Memoization
        if (dp[a][b] != -1) {
            return dp[a][b];
        }
  
        // Initialize ans as maximum as we have to find the  
        // minimum number of digits 
        int ans = 101;
  
        // Check for all possible combinations of digits
        for (int i = 9; i >= 1; i--) {
  
            // recurrence call 
            int k = minimumNumberOfDigits(a - i, b - (i * i));
  
            // If the combination of digits cannot give sum as a 
            // and sum of square of digits as b 
            if (k != -1) {
                ans = Math.min(ans, k + 1);
            }
        }
  
        // Returns the minimum number of digits
        return dp[a][b] = ans;
    }
  
// Function to print the digits that gives 
// sum as a and sum of square of digits as b
    static void printSmallestNumber(int a, int b) {
  
        // initialize the dp array as -1
        for (int[] row : dp) {
            Arrays.fill(row, -1);
        }
  
        // base condition 
        dp[0][0] = 0;
  
        // function call to get the minimum number of digits  
        int k = minimumNumberOfDigits(a, b);
  
        // When there does not exists any number
        if (k == -1 || k > 100) {
            System.out.println("-1");
        } else {
            // Printing the digits from the most significant digit
            while (a > 0 && b > 0) {
  
                // Trying all combinations 
                for (int i = 1; i <= 9; i++) {
                    // checking conditions for minimum digits
                    if (a >= i && b >= i * i
                            && 1 + dp[a - i][b - i * i] == dp[a][b]) {
                        System.out.print(i);
                        a -= i;
                        b -= i * i;
                        break;
                    }
                }
            }
        }
    }
  
// Driver Code
    public static void main(String args[]) {
        int a = 18, b = 162;
        // Function call to print the smallest number 
        printSmallestNumber(a, b);
    }
}
  
// This code is contributed by PrinciRaj19992


Python3
# Python3 program to find the Smallest number
# with given sum of digits and
# sum of square of digits
  
dp=[[-1 for i in range(8101)]for i in range(901)]
  
# Top down dp to find minimum number of digits with
# given sum of dits a and sum of square of digits as b
def minimumNumberOfDigits(a,b):
    # Invalid condition 
    if (a > b or a < 0 or b < 0 or a > 900 or b > 8100):
        return -1
          
    # Number of digits satisfied
    if (a == 0 and b == 0):
        return 0
          
    # Memoization
    if (dp[a][b] != -1):
        return dp[a][b]
          
    # Initialize ans as maximum as we have to find the
    # minimum number of digits
    ans = 101
      
    #Check for all possible combinations of digits
    for i in range(9,0,-1):
          
        # recurrence call
        k = minimumNumberOfDigits(a - i, b - (i * i))
          
        # If the combination of digits cannot give sum as a
        # and sum of square of digits as b 
        if (k != -1):
            ans = min(ans, k + 1)
              
    # Returns the minimum number of digits
    dp[a][b] = ans
    return ans
  
# Function to print the digits that gives
# sum as a and sum of square of digits as b
def printSmallestNumber(a,b):
    # initialize the dp array as
    for i in range(901):
        for j in range(8101):
            dp[i][j]=-1
              
    # base condition
    dp[0][0] = 0
      
    # function call to get the minimum number of digits
    k = minimumNumberOfDigits(a, b)
      
    # When there does not exists any number
    if (k == -1 or k > 100):
        print(-1,end='')
    else:
        # Printing the digits from the most significant digit
          
        while (a > 0 and b > 0):
              
            # Trying all combinations
            for i in range(1,10):
                  
                #checking conditions for minimum digits
                if (a >= i and b >= i * i and
                    1 + dp[a - i][b - i * i] == dp[a][b]):
                    print(i,end='')
                    a -= i
                    b -= i * i
                    break
# Driver Code
if __name__=='__main__':
    a = 18
    b = 162
# Function call to print the smallest number
    printSmallestNumber(a,b)
      
# This code is contributed by sahilshelangia


C#
// C# program to find the Smallest number 
// with given sum of digits and
// sum of square of digits
using System;
public class GFG {
   
    static int [,]dp = new int[901,8101];
   
// Top down dp to find minimum number of digits with
// given sum of dits a and sum of square of digits as b
    static int minimumNumberOfDigits(int a, int b) {
        // Invalid condition 
        if (a > b || a < 0 || b < 0 || a > 900 || b > 8100) {
            return -1;
        }
   
        // Number of digits satisfied
        if (a == 0 && b == 0) {
            return 0;
        }
   
        // Memoization
        if (dp[a,b] != -1) {
            return dp[a,b];
        }
   
        // Initialize ans as maximum as we have to find the  
        // minimum number of digits 
        int ans = 101;
   
        // Check for all possible combinations of digits
        for (int i = 9; i >= 1; i--) {
   
            // recurrence call 
            int k = minimumNumberOfDigits(a - i, b - (i * i));
   
            // If the combination of digits cannot give sum as a 
            // and sum of square of digits as b 
            if (k != -1) {
                ans = Math.Min(ans, k + 1);
            }
        }
   
        // Returns the minimum number of digits
        return dp[a,b] = ans;
    }
   
// Function to print the digits that gives 
// sum as a and sum of square of digits as b
    static void printSmallestNumber(int a, int b) {
   
        // initialize the dp array as -1
        for (int i = 0; i < dp.GetLength(0); i++)
            for (int j = 0; j < dp.GetLength(1); j++)
                   dp[i, j] = -1;
  
   
        // base condition 
        dp[0,0] = 0;
   
        // function call to get the minimum number of digits  
        int k = minimumNumberOfDigits(a, b);
   
        // When there does not exists any number
        if (k == -1 || k > 100) {
            Console.WriteLine("-1");
        } else {
            // Printing the digits from the most significant digit
            while (a > 0 && b > 0) {
   
                // Trying all combinations 
                for (int i = 1; i <= 9; i++) {
                    // checking conditions for minimum digits
                    if (a >= i && b >= i * i
                            && 1 + dp[a - i,b - i * i] == dp[a,b]) {
                        Console.Write(i);
                        a -= i;
                        b -= i * i;
                        break;
                    }
                }
            }
        }
    }
   
// Driver Code
    public static void Main() {
        int a = 18, b = 162;
        // Function call to print the smallest number 
        printSmallestNumber(a, b);
    }
}
   
// This code is contributed by PrinciRaj19992


输出:
99

时间复杂度:O(900 * 8100 * 9)
辅助空间:O(900 * 8100)

注意:时间复杂度以数字表示,因为我们正在尝试所有可能的数字组合。