📌  相关文章
📜  给定数字总和和数字平方和的最小数

📅  最后修改于: 2021-09-16 11:13:18             🧑  作者: 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  通过 i*i 和 break。继续重复上述过程以找到所有数字,直到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


Javascript


输出:
99

时间复杂度:O(900*8100*9)
辅助空间:O(900*8100)
注意:时间复杂度以数字形式表示,因为我们正在尝试所有可能的数字组合。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程