给定的数字总和和数字的平方和 .找出具有给定数字总和和数字平方和的最小数字。该号码不应超过 100 位数字。如果不存在这样的数字或如果位数超过 100,则打印 -1。
例子:
Input : a = 18, b = 162
Output : 99
Explanation : 99 is the smallest possible number whose sum of digits = 9 + 9 = 18 and sum of squares of digits is 92+92 = 162.
Input : a = 12, b = 9
Output : -1
方法:
由于最小数字可以是 100 位,因此无法存储。因此,解决它的第一步将是找到可以为我们提供数字总和的最小位数和数字的平方和为 .要找到最小位数,我们可以使用动态规划。 DP[a][b] 表示一个数的最小位数,其位数之和为和数字的平方和将是 .如果不存在任何这样的数字,则 DP[a][b] 将为 -1。
由于数字不能超过 100 位,因此 DP 数组的大小为101*8101 。迭代每个数字,并尝试所有可能的数字组合,这给我们的数字总和为和数字的平方和为 .使用以下递推关系将最小位数存储在 DP[a][b] 中:
DP[a][b] = min( minimumNumberOfDigits(a – i, b – (i * i)) + 1 )
where 1<=i<=9
得到最小位数后,找出数字。要查找数字,请检查所有组合并打印满足以下条件的数字:
1 + dp[a – i][b – i * i] == dp[a][b]
where 1<=i<=9
如果 i 中的任何一个满足上述条件,则减少由我和通过 i*i 和 break。继续重复上述过程以找到所有数字,直到是 0 并且是 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 现场工作专业课程和学生竞争性编程现场课程。