Multiplying two large vector variables - c++

The following code is to find the Maximum Pairwise Product (MPP) which is:
You're given an array of N integers and a number K. The maximum
K-product of the array is the maximum product of any K length subsequence of the array. For example, the maximum 2-product of the array
[-5, 3, 4, -6] is 30 because the product of the subsequence [-5, -6]
is 30 and it is impossible to achieve a larger subsequence products.
The code below calculates the MPP for every input except for "90000 and 100000" which must give an output 9,000,000,000, but I got 410065408:
int MaxPairwiseProduct(const vector<int>& numbers) {
int result = 0;
int n = numbers.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (numbers[i] * numbers[j] > result && numbers[i] * numbers[j] % 2 == 0) {
result = numbers[i] * numbers[j];
}
}
}
return result;
}
Sadly, these pages (1 and 2) did not help me with my request.

Because when you multiply your integer, it is outgoing of the int type boundaries. In this case, use the long long type:
long long MaxPairwiseProduct(const vector< long long >& numbers) {
long long result = 0;
int n = numbers.size();
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (numbers[i] * numbers[j] > result && numbers[i] * numbers[j] % 2 == 0) {
result = numbers[i] * numbers[j];
}
}
}
return result;
Please note that if your numbers are too big (bigger than 2^63-1) you can not use standard C++ types. There is all type boundaries C++ data types.

Related

Magical Subarrays in an Array

Can someone explain how to solve the question below, Much appreciated!
Given an integer array[] of size n, your task is to count the number of magical subarrays in the arr.
Here any subarray array[l…r] is considered to be magical if it satisfies the magical condition.
it should contain an even number(non zero) of odd numbers
More Formally the count of odd numbers in the subarray should be even and should be greater than 0
Constraints
1<=n<=10^5
1<=array[i]<=2*(10)^5
#TestCase 1;
Input:
n=4
array[]={2,1,2,3}
output:2
the magical subarrays are: {2,1,2,3} , {1,2,3}
#Testcase 2
n=6
array[]={1,2,5,2,3,7}
output:7
the magical subarrays are:{1,2,5}, {1,2,5,2}, {2,5,2,3}, {5,2,3}, {2,3,7}, {3,7}, {1,2,5,2,3,7}
The code below gives TLE for the above constraints
long long magicalSubarrays(int n,vector<int> arr)
{
vector<int> O;
for (int i = 0; i < arr.size(); i++) {
if (arr[i] % 2 == 1) {
O.push_back(i);
}
}
int k=O.size();
long long sum = 0;
for (int i = 0; i < O.size(); i++) {
for (int j = i + 1; j < O.size(); j += 2) {
int left = (i-1<0)? O[i]: O[i]-1-O[i-1];
int right= (j+1>=k)? n-1-O[j]: O[j+1]-1-O[j];
sum += (1 + left) * (1 + right);
}
}
return sum;
}
Let O be the array that contains all indices of odd elements.
Every magical subarray must then consist of:
every number from O[i] to O[j] inclusive (where j = i+1+2*k for some k)
an arbitrary number of even items left of i
an arbitrary number of even items right of j
Or, in C++-flavored pseudocode:
int magical_subarrays(const std::vector<int>& arr) {
std::vector<size_t> O;
for (int i = 0; i < arr.length(); i++) {
if (arr[i] % 2 == 1) {
O.push_back(i);
}
}
int sum = 0;
for (int i = 0; i < O.length(); i++) {
for (int j = i + 1; j < O.length(); j += 2) {
int left = /* exercise for the reader. It involves O[i] and O[i-1]. */
int right = /* exercise for the reader. It involves O[j] and O[j+1]. */
sum += (1 + left) * (1 + right);
}
}
return sum;
}

How can I make this function output max array value?

I'm new to C++ and trying to make this piece of code work properly. It's a basic algorithm for
prime numbers. I make an array the size of which is defined by the user input. Then I need to print
only the max prime number from this array. How can I do that here?
unsigned long long nPrime(unsigned n) {
long long *a = new long long[n + 1];
long long maxNum = a[n];
for (int i = 0; i < n + 1; i++) {
a[i] = i;
}
for (int j = 2; j < n + 1; j++) {
if (a[j] != 0) {
for (int k = j * j; k < n + 1; k += j) {
a[k] = 0;
}
cout << a[j] << endl;
}
}
return 0;
}
You can find the biggest number in an array using std::max_element from <algorithm>:
return *std::max_element(a, a+n);
But this isn't even necessary. Since the biggest prime will be the last prime you found, just keep track of that:
int biggestPrime = 2;
And then, when you found a prime:
biggestPrime = j;
You can also replace your array of long long with an array of bool, since the index already keeps track of the number:
unsigned long long nPrime(unsigned n) {
bool *a = new bool[n + 1]();
long long maxNum = a[n];
int biggestPrime = 2;
for (int j = 2; j < n + 1; j++) {
if (!a[j]) {
for (int k = j * j; k < n + 1; k += j) {
a[k] = true;
}
biggestPrime = j;
}
}
delete[] a;
return biggestPrime;
}
And last but not least, don't forget to delete your dynamically allocated memory when you're done:
delete[] a;
As it seems you mark non-prime numbers with value 0 in the array. We know that primes are positive numbers, to simplify, let maxNum be -1. Then I added one for at the and of the function which will calculate the maximum prime value in the array. This is the one way to do :
unsigned long long nPrime(unsigned n) {
long long *a = new long long[n + 1];
long long maxNum = -1;
for (long long i = 0; i < n + 1; i++) {
a[i] = i;
}
for (long long i = 2; i < n + 1; i++) {
for (long long k = i * i; k < n + 1; k += i) {
a[k] = 0;
}
}
for (long long i = 1; i < n; i++) {
if (a[i] != 0 && maxNum < a[i]) maxNum = a[i];
}
return maxNum;
}
Also instead of last for you can use faster version. In this version you don't even need maxNum value : let's start from the end and first value which is non zero will be the answer:
for (long long i = n; i >= 2; i--) {
if (a[i] != 0) return a[i];
}

figure out Uneaten Leaves algorithm bug

I faced this problem in an interview challenge
K caterpillars are eating their way through N leaves, each caterpillar
falls from leaf to leaf in a unique sequence, all caterpillars start
at a twig at position 0 and falls onto the leaves at position between
1 and N. Each caterpillar j has an associated jump number Aj. A
caterpillar with jump number j eats leaves at positions that are
multiple of j. It will proceed in the order j, 2j, 3j…. till it
reaches the end of the leaves and it stops and build its cocoon. Given
a set A of K elements , we need to determine the number
of uneaten leaves.
Constraints:
1 <= N <= 109
1 <= K <= 15
1 <= A[i] <= 109
Input format:
N = No of uneaten leaves.
K = No. of caterpillars.
A = Array of integer.
jump numbers Output:
The integer nu. Of uneaten leaves
Sample Input:
10
3
2
4
5
Output:
4
Explanation:
[2, 4, 5] is the 3-member set of jump numbers. All leaves which are multiple of 2, 4, and 5 are eaten. Only 4 leaves which are numbered 1,3,7,9 are left.
the naive approach for solving this question is have a Boolean array of all N numbers, and iterate over every caterpillar and remember the eaten leaves by it.
int uneatenusingNaive(int N, vector<int> A)
{
int eaten = 0;
vector<bool>seen(N+1, false);
for (int i = 0; i < A.size(); i++)
{
long Ai = A[i];
long j = A[i];
while (j <= N && j>0)
{
if (!seen[j])
{
seen[j] = true;
eaten++;
}
j += Ai;
}
}
return N - eaten;
}
this approach passed 8 out of 10 test cases and give wrong answer for 2 cases.
another approach using Inclusion Exclusion principle, explanation for it can be found here and here
below is my code for the second approach
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a%b);
}
int lcm(int i, int j)
{
return i*j / gcd(i, j);
}
vector<vector<int>> mixStr(vector<vector<int>> & mix, vector<int>& A, unordered_map<int, int> & maxStart)
{
vector<vector<int>> res;
if (mix.size() == 0)
{
for (int i = 0; i < A.size(); i++)
{
vector<int> tmp;
tmp.push_back(A[i]);
res.push_back(tmp);
}
return res;
}
for (int i = 0; i<mix.size(); i++)
{
int currSlotSize = mix[i].size();
int currSlotMax = mix[i][currSlotSize - 1];
for (int j = maxStart[currSlotMax]; j < A.size(); j++)
{
vector<int> tmp(mix[i]);
tmp.push_back(A[j]);
res.push_back(tmp);
}
}
return res;
}
int uneatenLeavs(int N, int k, vector<int> A)
{
int i = 0;
vector<vector<int>> mix;
bool sign = true;
int res = N;
sort(A.begin(), A.end());
unordered_map<int,int> maxStart;
for (int i = 0; i < A.size(); i++)
{
maxStart[A[i]] = i + 1;
}
int eaten = 0;
while (mix.size() != 1)
{
mix = mixStr(mix, A, maxStart);
for (int j = 0; j < mix.size(); j++)
{
int _lcm = mix[j][0];
for (int s = 1; s < mix[j].size(); s++)
{
_lcm = lcm(mix[j][s], _lcm);
}
if (sign)
{
res -= N / _lcm;
}
else
{
res += N / _lcm;
}
}
sign = !sign;
i++;
}
return res;
}
this approach passed only one 1/10 test case. and for the rest of test cases time limit exceeded and wrong answer.
Question:
What am I missing in first or second approach to be 100% correct.
Using Inclusion-Exclusion theorem is correct approach, however, your implementation seems to be too slow. We can use bitmasking technique to obtain a O(K*2^K) time complexity.
Take a look at this:
long result = 0;
for(int i = 1; i < 1 << K; i++){
long lcm = 1;
for(int j = 0; j < K; j++)
if(((1<<j) & i) != 0) //if bit j is set, compute new LCM after including A[j]
lcm *= A[j]/gcd(lcm, A[j]);
if(number of bit set in i is odd)
result += N/lcm;
else
result -= N/lcm;
}
For your first approach, an O(N*K) time complexity algorithm, with N = 10^9 and K = 15, it will be too slow, and can cause memory limit exceed/time limit exceed.
Notice that lcm can be larger than N, so, additional check is needed.

memory issue in using partially initialized array(in 0/1 knapsack)

Given n items with size Ai and value Vi, and a backpack with size m. What's the maximum value can you put into the backpack?
Have you met this question in a real interview? Yes
Example
Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.
Note
You cannot divide item into small pieces and the total size of items you choose should smaller or equal to m.
int knapsack(int m, vector<int> A, vector<int> V) {
int dp[m + 1], tmp[m + 1];
for (int n = 1; n <= m; n++) {
//******the problem would disappear if i change n to start with 0
dp[n] = (n < A[0]) ? 0 : V[0] ;
tmp[n] = dp[n];
}
for (int i = 1; i < A.size(); i++) {
for (int n = 1; n <= m; n++) {
tmp[n] = dp[n];
}
for (int j = 1; j <= m; j++) {
if (j >= A[i]) {
dp[j] = max(tmp[j], (V[i] + tmp[j - A[i]]));
}
}
}
return dp[m];
}
I am failing the specific testcase and all other are fine(even larger m values)
m = 10, A = [2,3,5,7], V = [1,5,2,4]
Output: 563858905 (actually random every time) Expected: 9
I know this question is some what trivial but I'm really curious about the memory allocation process in this scenario
I'm guessing that it would be dangerous to use any array that is not initialized at the first memory location, can someone confirm with me?
I tried following code, a simpler version of yours;
#include <iostream>
using namespace std;
int knapsack(int m, int A[], int V[], int size) {
int dp[m+1], tmp[m+1];
for (int n = 1; n <= m; n++) { //*1*
dp[n] = (n < A[0]) ? 0 : V[0] ;
tmp[n] = dp[n];
}
for (int i = 1; i < 4; i++) { //*2*
for (int n = 1; n <= m; n++) { //*3*
tmp[n] = dp[n];
}
for (int j = 1; j <= m; j++) { //*4*
if (j >= A[i]) {
dp[j] = (tmp[j]> (V[i] + tmp[j - A[i]])? //*5*
tmp[j] :
(V[i] + tmp[j - A[i]])
);
}
}
}
cout << "answer:" << dp[m] << endl;
return dp[m];
}
int main(){
int a[] = {2,3,5,7};
int b[] = {1,5,2,4};
knapsack(10, a, b, 4);
return 0;
}
and got 8 as the answer, rather than a random number.
I'm not sure that my code is the correct version of yours, but I luckily noticed that the expression of V[i] + tmp[j-A[i]] at the line marked by "\\*5" accesses tmp[0] when j=2 and i=1, since A[1] == 2 and 2 >= A[1]. Thus it would not be safe without initialization of tmp[0] in this logic.
So, I guess you are right; the uninitialized value of tmp[0] may change the result value, (and in some cases the flow of the logic as well, at the conditional statement of line //*5.)

Getting awkward results when trying to find largest product in array for project euler 11

I am asked to find the largest product of 4 adjacent numbers horizontally, diagonally, or vertically, in a 20x20 grid for project euler problem 11. The grid can be found here:http://projecteuler.net/problem=11.
I could not find a more efficient approach than to loop over the entire array 4 times. I made a variable max that was initially set equal to 0. I then looped over the array horizontally, and found the products. If a product was greater than max, max was set to that product, etc. I did this for all 4 loops. However, my answer is wrong, and probably too big.
#include <iostream>
using namespace std;
int main () {
int twenty_grid[20][20] =
{
{ 8, 2, 22, /* data elided since the question links to it */ },
…
}
int max = 0;
// Pass 1: This determines the greatest element horizontally
for (int i = 0; i < 20; ++i) {
for (int j = 0; j < 17; ++j) {
// j stops at 17 to avoid a segmentation fault.
int n = twenty_grid[i][j] *
twenty_grid[i][j+1] *
twenty_grid[i][j+2] *
twenty_grid[i][j+2] *
twenty_grid[i][j+3];
if (n > max)
max = n;
}
}
// Now we do the same loop, except we do i + 1, i + 2, etc,
// rather than j +1, j+2. This does it vertically. Pass 2:
for (int i = 0; i < 17; ++i) {
for (int j = 0; j < 20; ++j) {
int n = twenty_grid[i][j] *
twenty_grid[i+1][j] *
twenty_grid[i+2][j] *
twenty_grid[i+3][j];
if (n > max) {
max = n;
}
}
}
// Finally, we increment both i and j to get the diagonals.
for (int i = 0; i < 17; ++i) {
for (int j = 0; j < 20; ++j) {
int n = twenty_grid[i][j] *
twenty_grid[i+1][j+1] *
twenty_grid[i+2][j+2] *
twenty_grid[i+3][j+3];
if (n > max) {
max = n;
}
}
}
// For diagonals, 2 passes are needed to account for both directions.
for (int i = 0; i < 17; i++) {
for (int j = 3; j < 20; j++) {
int n = twenty_grid[i][j] *
twenty_grid[i + 1][i -1] *
twenty_grid[i + 2][i -2] *
twenty_grid[i + 3][i -3];
if (n > max)
max = n;
}
}
cout << max << endl;
return 0;
}
To take a look at why my answer was constantly wrong, I began to print out each individual product as it was calculated. To my surprise, many of them were negative. After checking my loops, it doesn't seem like they access any data out of the array. Could someone lead me in the right direction for fixing this code?
I found several problems.
The first block of code multiplies twenty_grid[i][j+2] twice.
In the third block of code the end condition for the inner loop should be j < 17.
The last block of code uses i as an array index instead of j in three places.
It produces the correct answer after fixing these issues.