给定两个数字, N和D。将以下两个操作中的任何一个应用于N :
- 将D加到N
- 改变N到digitsum(N),其中digitsum(N)是N个数字的总和
任务是将N转换为最小可能值。打印最小可能值N和应用给定操作的次数(其中任何一个)。操作次数必须最少。
例子:
Input : N = 2, D = 1
Output : 1 9
Perfome Type1 opeation 8 times and Type2 opeation 1 time
Input : N = 9, D = 3
Output : 3, 2
Apply one type1 operation first and then type2 operation
先决条件:
1.给定大整数的数字根(重复的数字和)
2.具有给定数字根的范围内的数字
方法 :
令Dr(x)是为整数x定义的函数,如下所示:
- 如果
0 <= x <= 9
,则Dr(x) = x
- 否则,
Dr(x) = Dr(Sum-of-digits(x))
函数Dr(x)是数字x的数字根。
-
Dr(a+b) = Dr(Dr(a) + Dr(b))
-
Dr(ab) = Dr(Dr(a) * Dr(b))
重要观察:对于某些非负整数k,最小值始终是: Dr(N + kD)
的最小值。
Dr(N + kD) = Dr(Dr(N) + Dr(kD)) (1)
现在, Dr(kd) = Dr(Dr(k) * Dr(D))
Dr(k)的可能值为0、1、2…9,由数字k = 0、1、2…9给出
Dr(x) = Dr(Sum-of-digits(x)) (2)
- N的最小值等于数字总和(N)的最小值。如果我们减少一次此答案并加上D,则可获得的最小值将保持不变。因此,如果需要先执行reduce操作再执行add操作,那么我们可以先执行add操作再执行reduce操作,而不会影响可能达到的根。从公式(1)和(2)的组合可以明显看出这一点。
- 因此,我们可以先执行所有加法运算,然后再进行所有归约运算,并达到任何一组操作可能达到的任何数量。使用以上权利要求,我们可以证明最小可能值是
Dr(N + kD)
的最小值,其中0 <= k <= 9
。 - 要查找最小步骤数,请注意加法和位数求和操作的相对顺序确实会影响答案。另外,请注意,“数字和”函数的降低非常快。
- <= 10的任何数字10等于<= 90的数字,任何<= 90的数字<= 18表示的数字,依此类推。简而言之,任何数字都可以以<= 5的步数减少到其数字根。
- 通过这一点,我们可以证明最小步长的值永远不会大于15。这是一个宽松的上限,而不是确切的上限。
- 使用蛮力递归算法,该算法在每个步骤都沿2个不同的方向分支,一个
x = Sum-of-digits(x)
,另一个为x = x+D
,但是直到递归深度为15为止。我们将在探索2种15种不同的方式后停下来。
下面是上述方法的实现:
C++
// CPP program to transform N to the minimum value
#include
using namespace std;
// Intialising the answer
int min_val = INT_MAX;
int min_steps = 0;
// Function to find the digitsum
int sumOfDigits(int n)
{
string s = to_string(n);
int sum = 0;
// Iterate over all digits and add them
for (int i = 0; i < s.length(); i++) {
sum += (s[i] - '0');
}
// Return the digit su,
return sum;
}
// Function to transform N to the minimum value
void Transform(int n, int d, int steps)
{
// If the final value is lesser than least value
if (n < min_val) {
min_val = n;
min_steps = steps;
}
// If final value is equal to least value then check
// for lesser number of steps to reach this value
else if (n == min_val) {
min_steps = min(min_steps, steps);
}
// The value will be obtained in less than 15 steps as
// proved so applying normal recursive operations
if (steps < 15) {
Transform(sumOfDigits(n), d, steps + 1);
Transform(n + d, d, steps + 1);
}
}
// Driver code
int main()
{
int N = 9, D = 3;
// Function call
Transform(N, D, 0);
// Print the answers
cout << min_val << " " << min_steps;
return 0;
}
Java
// JAVA program to transform N to the minimum value
import java.util.*;
class GFG{
// Intialising the answer
static int min_val = Integer.MAX_VALUE;
static int min_steps = 0;
// Function to find the digitsum
static int sumOfDigits(int n)
{
String s = String.valueOf(n);
int sum = 0;
// Iterate over all digits and add them
for (int i = 0; i < s.length(); i++) {
sum += (s.charAt(i) - '0');
}
// Return the digit su,
return sum;
}
// Function to transform N to the minimum value
static void Transform(int n, int d, int steps)
{
// If the final value is lesser than least value
if (n < min_val) {
min_val = n;
min_steps = steps;
}
// If final value is equal to least value then check
// for lesser number of steps to reach this value
else if (n == min_val) {
min_steps = Math.min(min_steps, steps);
}
// The value will be obtained in less than 15 steps as
// proved so applying normal recursive operations
if (steps < 15) {
Transform(sumOfDigits(n), d, steps + 1);
Transform(n + d, d, steps + 1);
}
}
// Driver code
public static void main(String[] args)
{
int N = 9, D = 3;
// Function call
Transform(N, D, 0);
// Print the answers
System.out.print(min_val+ " " + min_steps);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to transform N to the minimum value
import sys;
# Intialising the answer
min_val = sys.maxsize;
min_steps = 0;
# Function to find the digitsum
def sumOfDigits(n) :
s = str(n);
sum = 0;
# Iterate over all digits and add them
for i in range(len(s)) :
sum += (ord(s[i]) - ord('0'));
# Return the digit su,
return sum;
# Function to transform N to the minimum value
def Transform(n, d, steps) :
global min_val;global min_steps;
# If the final value is lesser than least value
if (n < min_val) :
min_val = n;
min_steps = steps;
# If final value is equal to least value then check
# for lesser number of steps to reach this value
elif (n == min_val) :
min_steps = min(min_steps, steps);
# The value will be obtained in less than 15 steps as
# proved so applying normal recursive operations
if (steps < 15) :
Transform(sumOfDigits(n), d, steps + 1);
Transform(n + d, d, steps + 1);
# Driver code
if __name__ == "__main__" :
N = 9; D = 3;
# Function call
Transform(N, D, 0);
# Print the answers
print(min_val, min_steps);
# This code is contributed by Yash_R
C#
// C# program to transform N to the minimum value
using System;
class GFG{
// Intialising the answer
static int min_val = int.MaxValue;
static int min_steps = 0;
// Function to find the digitsum
static int sumOfDigits(int n)
{
string s = n.ToString();
int sum = 0;
// Iterate over all digits and add them
for (int i = 0; i < s.Length; i++) {
sum += (s[i] - '0');
}
// Return the digit su,
return sum;
}
// Function to transform N to the minimum value
static void Transform(int n, int d, int steps)
{
// If the final value is lesser than least value
if (n < min_val) {
min_val = n;
min_steps = steps;
}
// If final value is equal to least value then check
// for lesser number of steps to reach this value
else if (n == min_val) {
min_steps = Math.Min(min_steps, steps);
}
// The value will be obtained in less than 15 steps as
// proved so applying normal recursive operations
if (steps < 15) {
Transform(sumOfDigits(n), d, steps + 1);
Transform(n + d, d, steps + 1);
}
}
// Driver code
public static void Main(string[] args)
{
int N = 9, D = 3;
// Function call
Transform(N, D, 0);
// Print the answers
Console.Write(min_val+ " " + min_steps);
}
}
// This code is contributed by Yash_R
输出:
3 2
时间复杂度: