How to reduce memory usage? Problem from code forces - c++

I solved this problem from codeforces: https://codeforces.com/problemset/problem/1471/B. But when I upload it it says memory limit exceeded. How can I reduce the memory usage? I used C++ for the problem. The problem was the following: "You have given an array a of length n and an integer x to a brand new robot. What the robot does is the following: it iterates over the elements of the array, let the current element be q. If q is divisible by x, the robot adds x copies of the integer qx to the end of the array, and moves on to the next element. Note that the newly added elements could be processed by the robot later. Otherwise, if q is not divisible by x, the robot shuts down.
Please determine the sum of all values of the array at the end of the process".
This is the code:
#include <iostream>
#include <cstdlib>
#include <vector>
using namespace std;
int main()
{
vector<int> vec;
vector<int> ans;
int temp;
int t;
cin >> t;
int a = 0;
int n, x;
for(int i=0; i<t; i++){
cin >> n >> x;
while(a<n){
cin >> temp;
a++;
vec.push_back(temp);
}
int q = 0;
while(true){
if(vec[q]%x == 0){
for(int copies=0; copies<x; copies++){
vec.push_back(vec[q]/x);
}
}
else{
break;
}
q++;
}
int sum = 0;
for(int z: vec){
sum += z;
}
ans.push_back(sum);
vec.clear();
a = 0;
}
for(int y: ans){
cout << y << endl;
}
return 0;
}
Thanks.

You don't need to build the array as specified to compute the sum
You might do:
int pow(int x, int n)
{
int res = 1;
for (int i = 0; i != n; ++i) {
res *= x;
}
return res;
}
int compute(const std::vector<int>& vec, int x)
{
int res = 0;
int i = 0;
while (true) {
const auto r = pow(x, i);
for (auto e : vec) {
if (e % r != 0) {
return res;
}
res += e;
}
++i;
}
}
Demo

Consider:
If you find an indivisible number in the original array, you're going to stop before you reach the numbers you have added (so they don't affect the result).
If you add q/x to the array but q/x isn't divisible by x, you're going to stop there when you reach it, if you haven't already stopped earlier. (On the other hand, if q/x is divisible by x, the sum of x copies of q/x is q, so adding them is equivalent to adding q.)
So you don't need to expand the array, you just need to sum the elements and - on the side - keep the sum of all the numbers you would have expanded with until you find one that is not a multiple of x.
Then you either add that to the sum of the array or not, depending on whether you reached the end of the array.

Related

How to solve runtime error in finding the largest number among n numbers

As I'm new to c++ I get runtime error for first example(I mean I tested my program with 5 examples it actually happens automatically by a site for testing) of my program I know that's because of exceeding time for running it but I dunno how to fix this.
My program get n numbers from user and finds the largest one and prints it.
#include<iostream>
#include<curses.h>
using namespace std;
int main()
{
int n;
cin >> n;
int *p = new int(n);
for(int i = 1; i<=n; i++){
cin >> *(p+i);
}
int largest = *p;
for(int i = 1; i<=n; i++){
if(largest < *(p+i))
largest = *(p+i);
}
cout << largest;
return(0);
}
int *p=new int(n);
The line above allocates just a single int, and sets the value to n. It does not allocate an array of n integers.
That line should be:
int *p=new int[n];
And then delete [] p; to deallocate the memory.
But better yet:
#include <vector>
//...
std::vector<int> p(n);
is the preferred way to utilize dynamic arrays in C++.
Then the input loop would simply be:
for(int i=0;i<n; i++)
{
cin >> p[i];
}
That same input loop could have been used if you had used the pointer version.
Then you have this error:
for(int i=1;i<=n;i++)
Arrays (and vectors) are indexed starting from 0 with the upper index at n-1, where n is the total number of elements. That loop has an off-by-one error, where it exceeds the upper index on the last loop.
Basically any loop that uses <= as the limiting condition is suspect. That line should be:
for(int i=0; i<n; i++)
(Note that I changed the code above to fix this error).
However ultimately, that entire loop to figure out the largest can be accomplished with a single line of code using the std::max_element function:
#include <algorithm>
//...
int largest = *std::max_element(p, p + n);
and if using std::vector:
#include <algorithm>
//...
int largest = *std::max_element(p.begin(), p.begin() + n);
I've commented on suggested changes in this slightly modified version:
#include <iostream>
int main()
{
unsigned n; // don't allow a negative amount of numbers
if(std::cin >> n) { // check that "cin >> n" succeeds
int* p=new int[n]; // allocate an array of n ints instead of one int with value n
for(int i=0; i < n; ++i) { // corrected bounds [0,n)
if(not (std::cin >> p[i])) return 1; // check that "cin >> ..." succeeds
}
int largest = p[0];
for(int i=1; i < n; ++i) { // corrected bounds again, [1,n)
if(largest < p[i])
largest = p[i];
}
delete[] p; // free the memory when done
std::cout << largest << '\n';
}
}
Note that using *(p + i) does the same as using p[i]. The latter is often preferred.
This would work if all cin >> ... works, but shows some of the hazards when using raw pointers. If extracting the n ints failes, the program will return 1 and leak the memory allocated with new int[n].
A rewrite using a smart pointer (std::unique_ptr<int[]>) that automatically deallocates the memory when it goes out of scope:
#include <iostream>
#include <memory> // std::unique_ptr
int main()
{
unsigned n;
if(std::cin >> n) {
std::unique_ptr<int[]> p(new int[n]);
for(int i=0; i < n; ++i) { // corrected bounds [0,n)
if(not (std::cin >> p[i])) return 1; // will not leak "p"
}
int largest = p[0];
for(int i=1; i < n; ++i) {
if(largest < p[i])
largest = p[i];
}
std::cout << largest << '\n';
} // p is automatically delete[]ed here
}
However, it's often convenient to store an array and its size together and to do this, you could use a std::vector<int> instead. It comes with a lot of convenient member functions, like, size() - and also begin() and end() which lets you use it in range-based for loops.
#include <iostream>
#include <vector> // std::vector
int main()
{
unsigned n;
if(std::cin >> n) {
std::vector<int> p(n); // a vector of n ints
// a range-based for loop, "elem" becomes a refrence to each element in "p":
for(int& elem : p) {
if(not (std::cin >> elem)) return 1;
}
int largest = p[0];
for(int i = 1; i < p.size(); ++i) { // using the size() member function
if(largest < p[i])
largest = p[i];
}
std::cout << largest << '\n';
}
}
That said, you don't need to store any number in an array to figure out what the largest number is. Instead, just compare the input with the currently largest number.
#include <iostream>
#include <limits> // std::numeric_limits
int main()
{
unsigned n;
if(std::cin >> n) {
// initialize with the smallest possible int:
int largest = std::numeric_limits<int>::min();
while(n--) {
int tmp;
if(not (std::cin >> tmp)) return 1;
if(largest < tmp)
largest = tmp;
}
std::cout << largest << '\n';
}
}

Program in C++ that takes 3 numbers and send them to a function and then calculate the average function of these 3 numbers

Program in C++ that takes 3 numbers and send them to a function and then calculate the average function of these 3 numbers.
I know how to do that without using a function ,for example for any n numbers I have the following program:
#include<stdio.h>
int main()
{
int n, i;
float sum = 0, x;
printf("Enter number of elements: ");
scanf("%d", &n);
printf("\n\n\nEnter %d elements\n\n", n);
for(i = 0; i < n; i++)
{
scanf("%f", &x);
sum += x;
}
printf("\n\n\nAverage of the entered numbers is = %f", (sum/n));
return 0;
}
Or this one which do that using arrays:
#include <iostream>
using namespace std;
int main()
{
int n, i;
float num[100], sum=0.0, average;
cout << "Enter the numbers of data: ";
cin >> n;
while (n > 100 || n <= 0)
{
cout << "Error! number should in range of (1 to 100)." << endl;
cout << "Enter the number again: ";
cin >> n;
}
for(i = 0; i < n; ++i)
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
sum += num[i];
}
average = sum / n;
cout << "Average = " << average;
return 0;
}
But is it possible to use functions?if yes then how? thank you so much for helping.
As an alternative to using fundamental types to store your values C++ provides std::vector to handle numeric storage (with automatic memory management) instead of plain old arrays, and it provides many tools, like std::accumulate. Using what C++ provides can substantially reduce your function to:
double avg (std::vector<int>& i)
{
/* return sum of elements divided by the number of elements */
return std::accumulate (i.begin(), i.end(), 0) / static_cast<double>(i.size());
}
In fact a complete example can require only a dozen or so additional lines, e.g.
#include <iostream>
#include <vector>
#include <numeric>
double avg (std::vector<int>& i)
{
/* return sum of elements divided by the number of elements */
return std::accumulate (i.begin(), i.end(), 0) / static_cast<double>(i.size());
}
int main (void) {
int n; /* temporary integer */
std::vector<int> v {}; /* vector of int */
while (std::cin >> n) /* while good integer read */
v.push_back(n); /* add to vector */
std::cout << "\naverage: " << avg(v) << '\n'; /* output result */
}
Above, input is taken from stdin and it will handle as many integers as you would like to enter (or redirect from a file as input). The std::accumulate simply sums the stored integers in the vector and then to complete the average, you simply divide by the number of elements (with a cast to double to prevent integer-division).
Example Use/Output
$ ./bin/accumulate_vect
10
20
34
done
average: 21.3333
(note: you can enter any non-integer (or manual EOF) to end input of values, "done" was simply used above, but it could just as well be 'q' or "gorilla" -- any non-integer)
It is good to work both with plain-old array (because there is a lot of legacy code out there that uses them), but equally good to know that new code written can take advantage of the nice containers and numeric routines C++ now provides (and has for a decade or so).
So, I created two options for you, one use vector and that's really comfortable because you can find out the size with a function-member and the other with array
#include <iostream>
#include <vector>
float average(std::vector<int> vec)
{
float sum = 0;
for (int i = 0; i < vec.size(); ++i)
{
sum += vec[i];
}
sum /= vec.size();
return sum;
}
float average(int arr[],const int n)
{
float sum = 0;
for (int i = 0; i < n; ++i)
{
sum += arr[i];
}
sum /= n;
return sum;
}
int main() {
std::vector<int> vec = { 1,2,3,4,5,6,99};
int arr[7] = { 1,2,3,4,5,6,99 };
std::cout << average(vec) << " " << average(arr, 7);
}
This is an example meant to give you an idea about what needs to be done. You can do this the following way:
// we pass an array "a" that has N elements
double average(int a[], const int N)
{
int sum = 0;
// we go through each element and we sum them up
for(int i = 0; i < N; ++i)
{
sum+=a[i];
}
// we divide the sum by the number of elements
// but we first have to multiply the number of elements by 1.0
// in order to prevent integer division from happening
return sum/(N*1.0);
}
int main()
{
const int N = 3;
int a[N];
cin >> a[0] >> a[1] >> a[2];
cout << average(a, N) << endl;
return 0;
}
how to do that without using a function
Quite simple. Just put your code in a function, let's call it calculateAverage and return the average value from it. What should this function take as input?
The list of numbers (array of numbers)
Total numbers (n)
So let's first get the input from the user and put it into the array, you have already done it:
for(int i = 0; i < n; ++i)
{
cout << i + 1 << ". Enter number: ";
cin >> num[i];
}
Now, lets make a small function i.e., calculateAverage():
int calculateAverage(int numbers[], int total)
{
int sum = 0; // always initialize your variables
for(int i = 0; i < total; ++i)
{
sum += numbers[i];
}
const int average = sum / total; // it is constant and should never change
// so we qualify it as 'const'
//return this value
return average
}
There are a few important points to note here.
When you pass an array into a function, you will loose size information i.e, how many elements it contains or it can contain. This is because it decays into a pointer. So how do we fix this? There are a couple of ways,
pass the size information in the function, like we passed total
Use an std::vector (when you don't know how many elements the user will enter). std::vector is a dynamic array, it will grow as required. If you know the number of elements beforehand, you can use std::array
A few problems with your code:
using namespace std;
Don't do this. Instead if you want something out of std, for e.g., cout you can do:
using std::cout
using std::cin
...
or you can just write std::cout everytime.
int n, i;
float num[100], sum=0.0, average;
Always initialize your variables before you use them. If you don't know the value they should be initialized to, just default initialize using {};
int n{}, i{};
float num[100]{}, sum=0.0, average{};
It is not mandatory, but good practice to declare variables on separate lines. This makes your code more readable.

(C++) Generate first p*n perfect square numbers in an array (p and n inputted from the keyboard)

I input p and n (int type) numbers from my keyboard, I want to generate the first p*n square numbers into the array pp[99]. Here's my code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int i, j, n, p, pp[19];
cout<<"n="; cin>>n;
cout<<"p="; cin>>p;
i=n*p;
j=-1;
while(i!=0)
{
if(sqrt(i)==(float)sqrt(i))
{
j++;
pp[j]=i;
}
i--;
}
for(i=0; i<n*p; i++)
cout<<pp[i]<<" ";
return 0;
}
But I am encountering the following problem: If I for example I enter p=3 and n=3, it will only show me the first 3 square numbers instead of 9, the rest 6 being zeros. Now I know why this happens, just not sure how to fix it (it's checking the first n * p natural numbers and seeing which are squares, not the first n*p squares).
If I take the i-- and add it in the if{ } statement then the algorithm will never end, once it reaches a non-square number (which will be instant unless the first one it checks is a perfect square) the algorithm will stop succeeding in iteration and will be blocked checking the same number an infinite amount of times.
Any way to fix this?
Instead of searching for them, generate them.
int square(int x)
{
return x * x;
}
int main()
{
int n = 0;
int p = 0;
std::cin >> n >> p;
int limit = n * p;
int squares[99] = {};
for (int i = 0; i < limit; i++)
{
squares[i] = square(i+1);
}
for (int i = 0; i < limit; i++)
{
std::cout << squares[i] << ' ';
}
}

Making a square() function without x*x in C++

I am self-studying C++ and the book "Programming-Principles and Practices Using C++" by Bjarne Stroustrup. One of the "Try This" asks this:
Implement square() without using the multiplication operator; that is, do the x*x by repeated addition (start a
variable result at 0 and add x to it x times). Then run some version of “the first program” using that square().
Basically, I need to make a square(int x) function that will return the square of it without using the multiplication operator. I so far have this:
int square(int x)
{
int i = 0;
for(int counter = 0; counter < x; ++counter)
{
i = i + x;
}
return i;
}
But I was wondering if there was a better way to do this. The above function works, but I am highly sure it is not the best way to do it. Any help?
Mats Petersson stole the idea out of my head even before I thought to think it.
#include <iostream>
template <typename T>
T square(T x) {
if(x < 0) x = T(0)-x;
T sum{0}, s{x};
while(s) {
if(s & 1) sum += x;
x <<= 1;
s >>= 1;
}
return sum;
}
int main() {
auto sq = square(80);
std::cout << sq << "\n";
}
int square(int x) {
int result = { 0 };
int *ptr = &result;
for (int i = 0; i < x; i++) {
*ptr = *ptr + x;
}
return *ptr;
}
I am reading that book atm. Here is my solution.
int square(int x)
{
int result = 0;
for (int counter = 0; counter < x; ++counter) result += x;
return result;
}
int square(int n)
{
// handle negative input
if (n<0) n = -n;
// Initialize result
int res = n;
// Add n to res n-1 times
for (int i=1; i<n; i++)
res += n;
return res;
}
//Josef.L
//Without using multiplication operators.
int square (int a){
int b = 0; int c =0;
//I don't need to input value for a, because as a function it already did it for me.
/*while(b != a){
b ++;
c = c + a;}*/
for(int b = 0; b != a; b++){ //reduce the workload.
c = c +a;
//Interesting, for every time b is not equal to a, it will add one to its value:
//In the same time, when it add one new c = old c + input value will repeat again.
//Hence when be is equal to a, c which intially is 0 already add to a for a time.
//Therefore, it is same thing as saying a * a.
}
return c;
}
int main(void){
int a;
cin >>a;
cout <<"Square of: "<<a<< " is "<<square(a)<<endl;
return 0;
}
//intricate.
In term of the running time complexity,your implementation is clear and simply enough,its running time is T(n)=Θ(n) for input n elements.Of course you also can use Divide-and-Conquer method,assuming split n elements to n/2:n/2,and finally recursive compute it then sum up two parts,that running time will be like
T(n)=2T(n/2)+Θ(n)=Θ(nlgn),we can find its running time complexity become worse than your implementation.
You can include <math.h> or <cmath> and use its sqrt() function:
#include <iostream>
#include <math.h>
int square(int);
int main()
{
int no;
std::cin >> no;
std::cout << square(no);
return 0;
}
int square(int no)
{
return pow(no, 2);
}

recursive algorithm to sum of every element in an array with a value lesser than x

I'm a beginner to c++ and I'm trying to write an recursive algorithm that returns the sum of every element in an array with a value less than x.
Here is my code:
#include <iostream>
using namespace std;
int sumOfElement(int xList[],int x, int lengthOfArray){
int sum = 0;
if (lengthOfArray == 0)
return sum;
else
for (int i=0; i <= lengthOfArray; i++) {
if(xList[i] < x)
return sum + xList[i];
else
sumOfElement(xList,x,lengthOfArray-1);
}
}
int main() {
cout << "Size of Array: ";
int size;
cin >> size;
int *xList = new int[size];
//Inputing array.
cout << "Enter elements of array followed by spaces: ";
for (int i = 0; i<size; i++)
cin >> xList[i];
cout << "Enter the integer value of x: " <<endl;
int limit;
cin >> limit;
cout << "Sum of every element in an array with a value less than x: " << sumOfElement(xList,limit,size) << endl;
return 0;
}
I'm using Visual Studio, while I was running the code, I got this warning: "warning C4715: 'sumOfElement' : not all control paths return a value. " And the program always stop executing when it asks me to enter the integer value for x.
What's wrong with my code?
Your approach here isn't really recursive. The idea with recursion is to consider a base case, and then consider how to reduce the problem at each step until you get to the base case.
For this problem:
The base case is when the length of the array is zero. In this case we return a sum of zero. (Intuitively: if the array is empty then we're adding nothing, giving a sum of zero.)
In order to reduce our array we look at the last element of the array (ie. at lengthOfArray - 1). We process this element: if it's less than x we add it, if it's not then we ignore it. We then get the result of processing the rest of the array by the same means (by calling the same function, but with a different array length), and add our result if applicable.
So, some example code:
int sumOfElement(int xList[], int x, int lengthOfArray){
if (lengthOfArray == 0) {
// base case
return 0;
} else {
int value = xList[lengthOfArray-1];
if (value < x) {
// process the rest of the array and add our result
return value + sumOfElement(xList, x, lengthOfArray - 1);
} else {
// process the rest of the array
return sumOfElement(xList, x, lengthOfArray - 1);
}
}
}
for (int i=0; i <= lengthOfArray; i++)
{
if(xList[i] < x)
return sum + xList[i];
else sumOfElement(xList,x,lengthOfArray-1);
}
You shouldn't have a for-loop, and recursive functions should "return" the deeper call, so
int retVal = 0;
if(xList[lengthOfArray-1] < x)
retval = xList[lengthOfArray-1]
return retVal + sumOfElement(xList,x,lengthOfArray-1);