# Minimize the cost of selecting two numbers whose product is X

**Prerequisite:** To Find Maximum and Minimum Prime Number

Given four integers **A, B, C and X**, the task is to minimize the cost of selecting two numbers **N** and **M** such that the product of N and M is equal to X, i.e. **N * M = X**. The **cost** to select the numbers N and M is decided as follows:

- For the first number N:
- The cost is A if N is a prime number.
- The cost is B if N is a composite number.
- The cost is C if N is 1.

- For the second number M (!= 1), the cost is M.

**Examples:**

Input:A = 7, B = 11, C = 2, X = 20Output:11Explanation:

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 = 40Output:3Explanation:

The minimum cost is when N = 20 and M = 2, Total cost = 1 + 2 = 3.

**Naive Approach:** Find all the factors of the number and check if the factor is prime or not, accordingly find the cost and select minimum from them.**Efficient Approach:** There can be three possible cases for **N** as follows:

**N is Prime:**Then the first number cost is fixed. In order to minimize the cost, the highest prime number possible is chosen such that**N ≠ X**.**N is Composite:**Similar to the above case, the maximum composite number that divides the number, but not the number itself has to be found. In order to do this, the minimum prime number that divides**X**is found and this is considered as**M**and cost is computed.**N is 1:**Any number can be formed(except when X = 1) and**M = X**for this case.

Therefore, the idea is to compute the cost for all the three cases and find the minimum among all. In order to do this, the list of all the minimum prime factors and maximum prime factors is precomputed using a slight variation of Sieve of Eratosthenes and stored in an array. The cost for all the three cases can be easily computed from these arrays.

Below is the implementation of the above approach:

## C++

`// C++ implementation of` `// the above approach` `#include <bits/stdc++.h>` `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` |

## Javascript

`<script>` `// Javascript implementation of the above approach` `let MAX = 1000;` ` ` ` ` `// max_prime[i] represents maximum prime` ` ` `// number that divides the number i` ` ` `let max_prime = Array.from({length: MAX}, (_, i) => 0);` ` ` ` ` `// min_prime[i] represents minimum prime` ` ` `// number that divides the number i` ` ` `let min_prime = Array.from({length: MAX}, (_, i) => 0);` ` ` ` ` `// Function to store the minimum` ` ` `// prime factor and the maximum` ` ` `// prime factor in two arrays` ` ` `function` `sieve(n)` ` ` `{` ` ` `for` `(let 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;` ` ` ` ` `let 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` ` ` `function` `findCost(A, B, C, X)` ` ` `{` ` ` `// Pre-calculation` ` ` `sieve(MAX);` ` ` ` ` `let N, M;` ` ` ` ` `// If X == 1, then there is no way to` ` ` `// find N and M. Prlet -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` ` ` `let min_cost = C + X;` ` ` ` ` `// Case 1` ` ` `// N is prime, first number cost is fixed` ` ` `// N is max_prime number divides this number` ` ` `let 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]) {` ` ` `let 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` ` ` ` ` `let A = 7, B = 11, C = 2, X = 20;` ` ` ` ` `document.write(findCost(A, B, C, X));` ` ` `</script>` |

**Output:**

11

Time Complexity: O(MAX)^{2}

Auxiliary Space: O(MAX)