给定两个数字和N和D 。将以下两个操作中的任何一个应用于N :
- 将D添加到N
- 改变N到digitsum(N),其中digitsum(N)是N个数字的总和
任务是将N转换为可能的最小值。打印N的最小可能值和应用给定操作的次数(其中任何一个)。操作次数必须最少。
例子:
Input : N = 2, D = 1
Output : 1 9
Perform Type1 operation 8 times and Type2 operation 1 time
Input : N = 9, D = 3
Output : 3, 2
Apply one type1 operation first and then type2 operation
先决条件:
1. 给定大整数的数字根(重复数字和)
2. 给定数字根范围内的数字
方法 :
令 Dr(x) 是一个为整数 x 定义的函数:
- Dr(x) = x,如果 0 <= x <= 9
- 否则,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;
// Initialising 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{
// Initialising 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;
# Initialising 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{
// Initialising 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
Javascript
输出:
3 2
时间复杂度:
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。