📌  相关文章
📜  将 N 转换为最小可能值

📅  最后修改于: 2021-10-26 06:42:39             🧑  作者: Mango

给定两个数字和ND 。将以下两个操作中的任何一个应用于N

  1. D添加到N
  2. 改变Ndigitsum(N),其中digitsum(N)N个数字的总和

任务是将N转换为可能的最小值。打印N的最小可能值和应用给定操作的次数(其中任何一个)。操作次数必须最少。
例子:

先决条件:
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

时间复杂度: O(T \cdot 2^{15} \cdot log_{10} N )

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