通过在每一步将 N 替换为其除数来最小化将 N 减少到 0 的操作
给定一个正整数N 。当N可以在每个操作中减少它的除数时,找到将N减少到0所需的最小操作数。
例子:
Input: N = 5
Output: 4
Explanation:
Reduce 5 as 5-1=4.
Reduce 4 as 4-2=2.
Reduce 2 as 2-1=1.
Reduce 1 as 1-1=0.
Input: N = 8
Output: 4
Explanation:
Reduce 8 as 8-4=4.
Reduce 4 as 4-2=2.
Reduce 2 as 2-1=1.
Reduce 1 as 1-1=0.
天真的方法:
One easy approach is to find highest divisor of N each time until N becomes 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)。