📌  相关文章
📜  通过在每一步将 N 替换为其除数来最小化将 N 减少到 0 的操作

📅  最后修改于: 2022-05-13 01:56:09.267000             🧑  作者: Mango

通过在每一步将 N 替换为其除数来最小化将 N 减少到 0 的操作

给定一个正整数N 。当N可以在每个操作中减少它的除数时,找到将N减少到0所需的最小操作数。

例子:

天真的方法:

请按照以下步骤解决此问题:

  • 遍历直到N变为0
  • 找到N 的最高除数并从 N减去。
  • 以这种方式计算N变为0所需的迭代次数
  • 返回上面计算的计数作为最终答案。
C++14
// C++ program to minimize operations
// to reduce N to 0 by replacing
// N by its divisor at each step
 
#include 
using namespace std;
 
typedef long long ll;
 
ll findElement(ll N)
{
    for (ll i = 2; i * i <= N; i++) {
        if (N % i == 0)
            return N / i;
    }
    return 1;
}
 
// Function to count minimum number
// of operation
ll minOperations(ll N)
{
    if (N < 0)
        return -1;
 
    ll count = 0;
    while (N) {
        ll divisor = findElement(N);
        N -= divisor;
        count++;
    }
    return count;
}
 
// Driver code
int main()
{
    ll N = 5;
    cout << minOperations(N);
 
    return 0;
}


Java
// Java program to minimize operations
// to reduce N to 0 by replacing
// N by its divisor at each step
import java.io.*;
 
class GFG {
 
  static long findElement(long N)
  {
    for (long i = 2; i * i <= N; i++) {
      if (N % i == 0)
        return N / i;
    }
    return 1;
  }
 
  // Function to count minimum number
  // of operation
  static long minOperations(long N)
  {
    if (N < 0)
      return -1;
 
    long count = 0;
    while (N > 0) {
      long divisor = findElement(N);
      N -= divisor;
      count++;
    }
    return count;
  }
 
  // Driver code
  public static void main (String[] args) {
    long N = 5;
    System.out.print(minOperations(N));
  }
}
 
// This code is contributed by hrithikgarg03188.


Python3
# Python3 program to minimize operations
# to reduce N to 0 by replacing N by its
# divisor at each step
 
# function to find the element
def findElement(N):
    i = 2
    while i * i <= N:
        if N % i == 0:
            return int(N / i)
        i += 1
    return 1
 
# function to count the min number of operations
def minOperations(N):
    if N < 0:
        return -1
    count = 0
    while N:
        divisor = findElement(N)
        N -= divisor
        count += 1
    return count
 
# Driver Code
N = 5
print(minOperations(N))
 
# This code is contributed by phasing17


C#
// C# program to minimize operations
// to reduce N to 0 by replacing
// N by its divisor at each step
using System;
class GFG {
  static long findElement(long N)
  {
    for (long i = 2; i * i <= N; i++) {
      if (N % i == 0)
        return N / i;
    }
    return 1;
  }
 
  // Function to count minimum number
  // of operation
  static long minOperations(long N)
  {
    if (N < 0)
      return -1;
 
    long count = 0;
    while (N > 0) {
      long divisor = findElement(N);
      N -= divisor;
      count++;
    }
    return count;
  }
 
  // Driver code
  public static void Main()
  {
    long N = 5;
    Console.WriteLine(minOperations(N));
  }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript


C++14
// C++ program to minimize operations
// to reduce N to 0 by replacing
// N by its divisor at each step
 
#include 
using namespace std;
typedef long long ll;
#define MAX 10000001
ll sieve[MAX];
 
// Function to calculate sieve
void makeSieve()
{
    ll i, j;
    sieve[0] = 0;
    sieve[1] = 1;
 
    for (i = 2; i < MAX; i++)
        sieve[i] = 0;
 
    for (i = 2; i * i <= MAX; i++) {
        if (!sieve[i]) {
            sieve[i] = i;
            for (j = i * i; j < MAX; j += i)
                if (!sieve[j])
                    sieve[j] = i;
        }
    }
    for (i = 2; i < MAX; i++) {
        if (!sieve[i])
            sieve[i] = 1;
        else
            sieve[i] = i / sieve[i];
    }
}
 
// Function to count minimum operations
ll minOperations(ll& N)
{
    if (N < 0)
        return -1;
 
    ll count = 0;
    makeSieve();
    while (N) {
        N -= sieve[N];
        count++;
    }
    return count;
}
 
// Driver Code
int main()
{
    ll N = 8;
    cout << minOperations(N);
 
    return 0;
}


Python3
# Python3 code to implement the above approach
 
MAX = 10000001
 
 
def makeSieve():
    sieve = [0] * MAX
    sieve[1] = 1
    for i in range(2, 1 + int(MAX ** 0.5)):
        if not sieve[i]:
            sieve[i] = i
            for j in range(i ** 2, MAX):
                if not sieve[j]:
                    sieve[j] = i
    for i in range(2, MAX):
        if not sieve[i]:
            sieve[i] = 1
        else:
            sieve[i] = (i // sieve[i])
    return sieve
 
 
def minOperations(N):
    if N < 0:
        return -1
    count = 0
    sieve = makeSieve()
    while N > 0:
        N -= (sieve[N])
        count += 1
    return count
 
 
# Driver Code
N = 8
print(minOperations(N))


C#
// C# implementation of above approach
using System;
 
class GFG{
 
  static int MAX= 10000001;
  static int[] sieve = new int[MAX];
 
  // Function to calculate sieve
  static void makeSieve()
  {
    int i, j;
    sieve[0] = 0;
    sieve[1] = 1;
 
    for (i = 2; i < MAX; i++)
      sieve[i] = 0;
 
    for (i = 2; i * i <= MAX; i++) {
      if (sieve[i]==0) {
        sieve[i] = i;
        for (j = i * i; j < MAX; j += i)
          if (sieve[j]==0)
            sieve[j] = i;
      }
    }
    for (i = 2; i < MAX; i++) {
      if (sieve[i]==0)
        sieve[i] = 1;
      else
        sieve[i] = i / sieve[i];
    }
  }
 
  // Function to count minimum operations
  static int minOperations(int N)
  {
    if (N < 0)
      return -1;
 
    int count = 0;
    makeSieve();
    while (N != 0) {
      N -= sieve[N];
      count++;
    }
    return count;
  }
 
  // Driver Code
  static public void Main (){
 
    int N = 8;
    Console.Write(minOperations(N));
  }
}
 
// This code is contributed by code_hunt.


输出:
4

时间复杂度: O(N^(3/2))
辅助空间: O(1)

有效的方法:上述解决方案可以使用预先计算优化,使用Eratosthenes 筛获得最小的素因子,并对其进行一些修改以存储N的最高因子。

请按照以下步骤解决此问题:

  • 使用Eratosthenes 筛法预先计算筛子以获得数字的最小素数,直到N
  • 通过为所有值存储1来修改上述筛子,否则为每个第 i 个值存储i/sieve[i]
  • 遍历直到N变为0
  • 为 N 的每次迭代减去sieve[N]
  • 以这种方式计算N变为0所需的迭代次数
  • 返回上面计算的计数作为最终答案。

C++14

// C++ program to minimize operations
// to reduce N to 0 by replacing
// N by its divisor at each step
 
#include 
using namespace std;
typedef long long ll;
#define MAX 10000001
ll sieve[MAX];
 
// Function to calculate sieve
void makeSieve()
{
    ll i, j;
    sieve[0] = 0;
    sieve[1] = 1;
 
    for (i = 2; i < MAX; i++)
        sieve[i] = 0;
 
    for (i = 2; i * i <= MAX; i++) {
        if (!sieve[i]) {
            sieve[i] = i;
            for (j = i * i; j < MAX; j += i)
                if (!sieve[j])
                    sieve[j] = i;
        }
    }
    for (i = 2; i < MAX; i++) {
        if (!sieve[i])
            sieve[i] = 1;
        else
            sieve[i] = i / sieve[i];
    }
}
 
// Function to count minimum operations
ll minOperations(ll& N)
{
    if (N < 0)
        return -1;
 
    ll count = 0;
    makeSieve();
    while (N) {
        N -= sieve[N];
        count++;
    }
    return count;
}
 
// Driver Code
int main()
{
    ll N = 8;
    cout << minOperations(N);
 
    return 0;
}

Python3

# Python3 code to implement the above approach
 
MAX = 10000001
 
 
def makeSieve():
    sieve = [0] * MAX
    sieve[1] = 1
    for i in range(2, 1 + int(MAX ** 0.5)):
        if not sieve[i]:
            sieve[i] = i
            for j in range(i ** 2, MAX):
                if not sieve[j]:
                    sieve[j] = i
    for i in range(2, MAX):
        if not sieve[i]:
            sieve[i] = 1
        else:
            sieve[i] = (i // sieve[i])
    return sieve
 
 
def minOperations(N):
    if N < 0:
        return -1
    count = 0
    sieve = makeSieve()
    while N > 0:
        N -= (sieve[N])
        count += 1
    return count
 
 
# Driver Code
N = 8
print(minOperations(N))

C#

// C# implementation of above approach
using System;
 
class GFG{
 
  static int MAX= 10000001;
  static int[] sieve = new int[MAX];
 
  // Function to calculate sieve
  static void makeSieve()
  {
    int i, j;
    sieve[0] = 0;
    sieve[1] = 1;
 
    for (i = 2; i < MAX; i++)
      sieve[i] = 0;
 
    for (i = 2; i * i <= MAX; i++) {
      if (sieve[i]==0) {
        sieve[i] = i;
        for (j = i * i; j < MAX; j += i)
          if (sieve[j]==0)
            sieve[j] = i;
      }
    }
    for (i = 2; i < MAX; i++) {
      if (sieve[i]==0)
        sieve[i] = 1;
      else
        sieve[i] = i / sieve[i];
    }
  }
 
  // Function to count minimum operations
  static int minOperations(int N)
  {
    if (N < 0)
      return -1;
 
    int count = 0;
    makeSieve();
    while (N != 0) {
      N -= sieve[N];
      count++;
    }
    return count;
  }
 
  // Driver Code
  static public void Main (){
 
    int N = 8;
    Console.Write(minOperations(N));
  }
}
 
// This code is contributed by code_hunt.
输出:
4

时间复杂度: O(N * log(log N)
辅助空间: O(MAX),其中 MAX 是筛子的极限(这里 MAX = 10000001)。