先决条件:查找最大和最小素数
给定四个整数A,B,C和X ,任务是最小化选择两个数字N和M的成本,以使N和M的乘积等于X,即N * M = X。选择数字N和M的成本决定如下:
- 对于第一个数字N:
- 如果N是质数,则成本为A。
- 如果N是一个复合数,则成本为B。
- 如果N为1,则成本为C。
- 对于第二个数字M(!= 1),成本为M。
例子:
Input: A = 7, B = 11, C = 2, X = 20
Output: 11
Explanation:
The following are the possible values and the cost for each pair:
Let N = 1 and M = 20, cost used in selecting N as 1 is C = 2, Total cost = 2 + 20 = 22.
Let N = 2 and M = 10, cost used in selecting N as prime number is A = 7, Total cost = 7 + 10 = 17
Let N = 4 and M = 5, cost used in selecting N as composite number is B = 11, Total cost = 11 + 5 = 15
Let N = 5 and M = 4, cost used in selecting N as prime number is A = 7, Total cost = 7 + 4 = 11
Let N = 10 and M = 2, cost used in selecting N as composite number is B = 11, Total cost = 11 + 2 = 13
Minimum among all the above is 11.
Input: A = 1, B = 1, C = 1, X = 40
Output: 3
Explanation:
The minimum cost is when N = 20 and M = 2, Total cost = 1 + 2 = 3.
幼稚的方法:找到所有数量的因子,并检查因子是否为质数,从而找到成本并从中选择最小值。
高效的方法: N可能有以下三种可能的情况:
- N是素数:那么第一个数字成本是固定的。为了最小化成本,选择尽可能高的质数,使得N≠X 。
- N是复合数字:类似于上述情况,最大的复合数字除以数字,但不必找到数字本身。为此,找到除以X的最小素数并将其视为M,并计算成本。
- N为1:可以形成任何数字(在X = 1时除外),并且在这种情况下M =X 。
因此,该想法是针对这三种情况计算成本,并在所有情况中找到最小值。为此,使用最小化的Eratosthenes筛网对所有最小质数因子和最大质数因子的列表进行预先计算,并将其存储在数组中。可以从这些数组轻松计算出所有三种情况的成本。
下面是上述方法的实现:
C++
// C++ implementation of
// the above approach
#include
using namespace std;
const int MAX = 100000;
// max_prime[i] represents maximum prime
// number that divides the number i
int max_prime[MAX];
// min_prime[i] represents minimum prime
// number that divides the number i
int min_prime[MAX];
// Function to store the minimum
// prime factor and the maximum
// prime factor in two arrays
void sieve(int n)
{
for (int i = 2; i <= n; ++i) {
// Check for prime number
// if min_prime[i] > 0,
// then it is not a prime number
if (min_prime[i] > 0) {
continue;
}
// If i is a prime number,
// then both minimum and maximum
// prime numbers that divide
// the number is the number itself
min_prime[i] = i;
max_prime[i] = i;
int j = i + i;
while (j <= n) {
if (min_prime[j] == 0) {
// If this number is being visited
// for first time then this divisor
// must be the smallest prime number
// that divides this number
min_prime[j] = i;
}
// Update prime number till the last
// prime number that divides this number
// The last prime number that
// divides this number will be maximum.
max_prime[j] = i;
j += i;
}
}
}
// Function to minimize the cost of finding
// two numbers for every number such that
// the product of those two is equal to X
int findCost(int A, int B, int C, int X)
{
// Pre-calculation
sieve(MAX);
int N, M;
// If X == 1, then there is no way to
// find N and M. Print -1
if (X == 1) {
return -1;
}
// Case 3 is always valid and cost for that
// is C + X C for choosing 1 and M = X/1
int min_cost = C + X;
// Case 1
// N is prime, first number cost is fixed
// N is max_prime number divides this number
int cost_for_prime = A;
N = max_prime[X];
// If X is prime then the maximum prime number
// is the number itself. For this case,
// M becomes 1 and this shouldn't be considered.
if (N != X) {
// Find M for this case
M = X / N;
// Add cost for the second number also
cost_for_prime += M;
// Update min_cost, if the
// cost for prime is minimum
min_cost = min(min_cost, cost_for_prime);
}
// Case 2
// If N is composite
// For this find the minimum prime number
// that divides A[i] and consider this as M
M = min_prime[X];
// Find N for that number
N = X / M;
// Check if this number is composite or not
// if N is prime then there is no way
// to find any composite number that divides X
// If N = min_prime[N] then N is prime
if (N != min_prime[N]) {
int cost_for_comp = B + M;
// Update min_cost, if the
// cost for the composite is minimum
min_cost = min(min_cost, cost_for_comp);
}
return min_cost;
}
// Driver code
int main()
{
int A = 7, B = 11, C = 2, X = 20;
cout << findCost(A, B, C, X) << " ";
return 0;
}
Java
// Java implementation of the above approach
class GFG {
static final int MAX = 1000;
// max_prime[i] represents maximum prime
// number that divides the number i
static int max_prime[] = new int[MAX];
// min_prime[i] represents minimum prime
// number that divides the number i
static int min_prime[] = new int[MAX];
// Function to store the minimum
// prime factor and the maximum
// prime factor in two arrays
static void sieve(int n)
{
for (int i = 2; i < n; ++i) {
// Check for prime number
// if min_prime[i] > 0,
// then it is not a prime number
if (min_prime[i] > 0) {
continue;
}
// If i is a prime number,
// then both minimum and maximum
// prime numbers that divide
// the number is the number itself
min_prime[i] = i;
max_prime[i] = i;
int j = i + i;
while (j < n) {
if (min_prime[j] == 0) {
// If this number is being visited
// for first time then this divisor
// must be the smallest prime number
// that divides this number
min_prime[j] = i;
}
// Update prime number till the last
// prime number that divides this number
// The last prime number that
// divides this number will be maximum.
max_prime[j] = i;
j += i;
}
}
}
// Function to minimize the cost of finding
// two numbers for every number such that
// the product of those two is equal to X
static int findCost(int A, int B, int C, int X)
{
// Pre-calculation
sieve(MAX);
int N, M;
// If X == 1, then there is no way to
// find N and M. Print -1
if (X == 1) {
return -1;
}
// Case 3 is always valid and cost for that
// is C + X C for choosing 1 and M = X/1
int min_cost = C + X;
// Case 1
// N is prime, first number cost is fixed
// N is max_prime number divides this number
int cost_for_prime = A;
N = max_prime[X];
// If X is prime then the maximum prime number
// is the number itself. For this case,
// M becomes 1 and this shouldn't be considered.
if (N != X) {
// Find M for this case
M = X / N;
// Add cost for the second number also
cost_for_prime += M;
// Update min_cost, if the
// cost for prime is minimum
min_cost = Math.min(min_cost, cost_for_prime);
}
// Case 2
// If N is composite
// For this find the minimum prime number
// that divides A[i] and consider this as M
M = min_prime[X];
// Find N for that number
N = X / M;
// Check if this number is composite or not
// if N is prime then there is no way
// to find any composite number that divides X
// If N = min_prime[N] then N is prime
if (N != min_prime[N]) {
int cost_for_comp = B + M;
// Update min_cost, if the
// cost for the composite is minimum
min_cost = Math.min(min_cost, cost_for_comp);
}
return min_cost;
}
// Driver code
public static void main (String[] args)
{
int A = 7, B = 11, C = 2, X = 20;
System.out.println(findCost(A, B, C, X));
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of
# the above approach
MAX = 10000;
# max_prime[i] represents maximum prime
# number that divides the number i
max_prime = [0]*MAX;
# min_prime[i] represents minimum prime
# number that divides the number i
min_prime = [0]*MAX;
# Function to store the minimum
# prime factor and the maximum
# prime factor in two arrays
def sieve(n) :
for i in range(2, n) :
# Check for prime number
# if min_prime[i] > 0,
# then it is not a prime number
if (min_prime[i] > 0) :
continue;
# If i is a prime number,
# then both minimum and maximum
# prime numbers that divide
# the number is the number itself
min_prime[i] = i;
max_prime[i] = i;
j = i + i;
while (j < n) :
if (min_prime[j] == 0) :
# If this number is being visited
# for first time then this divisor
# must be the smallest prime number
# that divides this number
min_prime[j] = i;
# Update prime number till the last
# prime number that divides this number
# The last prime number that
# divides this number will be maximum.
max_prime[j] = i;
j += i;
# Function to minimize the cost of finding
# two numbers for every number such that
# the product of those two is equal to X
def findCost(A, B, C, X) :
# Pre-calculation
sieve(MAX);
# If X == 1, then there is no way to
# find N and M. Print -1
if (X == 1) :
return -1;
# Case 3 is always valid and cost for that
# is C + X C for choosing 1 and M = X/1
min_cost = C + X;
# Case 1
# N is prime, first number cost is fixed
# N is max_prime number divides this number
cost_for_prime = A;
N = max_prime[X];
# If X is prime then the maximum prime number
# is the number itself. For this case,
# M becomes 1 and this shouldn't be considered.
if (N != X) :
# Find M for this case
M = X // N;
# Add cost for the second number also
cost_for_prime += M;
# Update min_cost, if the
# cost for prime is minimum
min_cost = min(min_cost, cost_for_prime);
# Case 2
# If N is composite
# For this find the minimum prime number
# that divides A[i] and consider this as M
M = min_prime[X];
# Find N for that number
N = X // M;
# Check if this number is composite or not
# if N is prime then there is no way
# to find any composite number that divides X
# If N = min_prime[N] then N is prime
if (N != min_prime[N]) :
cost_for_comp = B + M;
# Update min_cost, if the
# cost for the composite is minimum
min_cost = min(min_cost, cost_for_comp);
return min_cost;
# Driver code
if __name__ == "__main__" :
A = 7; B = 11; C = 2; X = 20;
print(findCost(A, B, C, X)) ;
# This code is contributed by AnkitRai01
C#
// C# implementation of the above approach
using System;
class GFG {
static int MAX = 1000;
// max_prime[i] represents maximum prime
// number that divides the number i
static int []max_prime = new int[MAX];
// min_prime[i] represents minimum prime
// number that divides the number i
static int []min_prime = new int[MAX];
// Function to store the minimum
// prime factor and the maximum
// prime factor in two arrays
static void sieve(int n)
{
for (int i = 2; i < n; ++i) {
// Check for prime number
// if min_prime[i] > 0,
// then it is not a prime number
if (min_prime[i] > 0) {
continue;
}
// If i is a prime number,
// then both minimum and maximum
// prime numbers that divide
// the number is the number itself
min_prime[i] = i;
max_prime[i] = i;
int j = i + i;
while (j < n) {
if (min_prime[j] == 0) {
// If this number is being visited
// for first time then this divisor
// must be the smallest prime number
// that divides this number
min_prime[j] = i;
}
// Update prime number till the last
// prime number that divides this number
// The last prime number that
// divides this number will be maximum.
max_prime[j] = i;
j += i;
}
}
}
// Function to minimize the cost of finding
// two numbers for every number such that
// the product of those two is equal to X
static int findCost(int A, int B, int C, int X)
{
// Pre-calculation
sieve(MAX);
int N, M;
// If X == 1, then there is no way to
// find N and M. Print -1
if (X == 1) {
return -1;
}
// Case 3 is always valid and cost for that
// is C + X C for choosing 1 and M = X/1
int min_cost = C + X;
// Case 1
// N is prime, first number cost is fixed
// N is max_prime number divides this number
int cost_for_prime = A;
N = max_prime[X];
// If X is prime then the maximum prime number
// is the number itself. For this case,
// M becomes 1 and this shouldn't be considered.
if (N != X) {
// Find M for this case
M = X / N;
// Add cost for the second number also
cost_for_prime += M;
// Update min_cost, if the
// cost for prime is minimum
min_cost = Math.Min(min_cost, cost_for_prime);
}
// Case 2
// If N is composite
// For this find the minimum prime number
// that divides A[i] and consider this as M
M = min_prime[X];
// Find N for that number
N = X / M;
// Check if this number is composite or not
// if N is prime then there is no way
// to find any composite number that divides X
// If N = min_prime[N] then N is prime
if (N != min_prime[N]) {
int cost_for_comp = B + M;
// Update min_cost, if the
// cost for the composite is minimum
min_cost = Math.Min(min_cost, cost_for_comp);
}
return min_cost;
}
// Driver code
public static void Main (string[] args)
{
int A = 7, B = 11, C = 2, X = 20;
Console.WriteLine(findCost(A, B, C, X));
}
}
// This code is contributed by AnkitRai01
11