I have created a program where I first set the size of the array and how many times I will look for consecutive values, then I fill in the array and finally I insert the consecutive values, it should look for the least consecutive value it finds in the array.
consecutive value means the sum of the elements in the array consecutively.
example:
7 4 // Array size and consecutive values
6 4 2 7 10 5 1 // arrangement
1 3 4 2 // Consecutive values
Answer = 1,12,19,6
Explanation
The lowest element of the array is the one in the last position which is 1, the answer is equal to 1.
the lowest segment is the one furthest to the left 6 4 2, the sum of which equals 12.
the answer is obtained by choosing segment 6 4 2 7, which equals 19.
there are two segments with a minimum cost equal to 6, segments 4 2 and 5 1.
How can it be improved?
#include<iostream>
#include<vector>
using namespace std;
void suma_elementos(int elemento);
vector<int>elementos, consecutivos;
int n, q, consecutivo, total, final = 99999999;
int main()
{
cin >> n >> q;
elementos.resize(n);
consecutivos.resize(q);
for (int i = 0; i < n; i++)
{
cin >> elementos[i];
}
for (int i = 0; i < q; i++)
{
cin >> consecutivos[i];
}
for (int i = 0; i < q; i++)
{
suma_elementos(consecutivos[i]);
for (int j = 0; j < consecutivo; j++)
{
for (int c = 0; c < consecutivos[i]; c++)
{
total += elementos[c + j];
}
if (total < final)
{
final = total;
}
total = 0;
}
cout << final << " ";
//reset
consecutivo = 0;
final = 99999999;
total = 0;
}
return 0;
}
//Suma de elementos
void suma_elementos(int elemento)
{
int proporcion = n;
while (proporcion >= elemento)
{
proporcion--;
consecutivo++;
}
}
edit 1:The program in small arrangements works well, but in large ones it's very slow
edit 2:must not have negative numbers in the sequence
1 Answer 1
Avoid globals.
consecutivo
is particularly confusing. It is too easy to miss the fact that it is reset to 0 at each iteration. Always prefer returning a value:int suma_elementos(int elemento) { int proporcion = n; int consecutivo = 0; while (proporcion >= elemento) { proporcion--; consecutivo++; } return consecutivo; }
and use it in your loop as
int consecutivo = suma_elementos(consecutivos[i]);
Now it is obvious that
suma_elementos
does not really need to loop. You have an invariantproporcion + consecutivo == n
. At the end of the last iteration you also haveproporcion == elemento
, which means thatconsecutivo = n - elemento
. In other words,int suma_elementos(int elemento) { return n - elemento; }
Now I would rather not bother to have
suma_elementos
at all (besides, with my poor Spanish I have an impression that the name is rather misleading). The loop would becomefor (int j = 0; j < n - consecutivos[i]; j++)
Honestly, it is much easier to understand.
final = 99999999;
is very fragile. Consider a ramp-up loop:final = 0; for (int j = 0; j < consecutivos[i]; j++) { total += elementos[j]; }
Your code complexity is \$O(n*k)\$ (
k
being a width of the window). Notice that after the ramp-up you don't need to recompute the sums ofk
elements: as the window shifts, one element enters, another leaves:final = total; for (int leave = 0, enter = base[i]; enter < n; leave++, enter++) { total += elementos[enter] - elementos[leave]; if (total < final) { final = total; } }
obtaining \$O(n + k)\$ complexity.
Explore related questions
See similar questions with these tags.
cin >> valor; recorrido.push_back(valor);
this block cannot be profiled correctly, since time taken by a human to enter a number is far more than the time apush_back
takes. \$\endgroup\$programming-challenge
flag and add a link to the challenge. Nice question otherwise. \$\endgroup\$