How to find Minimum Maximum sum c++ - c++

I've written some code in c++ that is meant to find the minimum and maximum values that can be calculated by summing 4 of the 5 integers presented in an array. My thinking was that I could add up all elements of the array and loop through subtracting each of the elements to figure out which subtraction would lead to the smallest and largest totals. I know this isn't the smartest way to do it, but I'm just curious why this brute force method isn't working when I code it. Any feedback would be very much appreciated.
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
void minimaxsum(vector<int> arr){
int i,j,temp;
int n=sizeof(arr);
int sum=0;
int low=INT_MAX;
int high=0;
for (j=0;j<n;j++){
for (i=0;i<n;i++){
sum+=arr[i];
}
temp=sum-arr[j];
if(temp<low){
low=temp;
}
else if(temp>high){
high=temp;
}
}
cout<<low;
cout<<high<<endl;
}
int main (){
vector<int> arr;
arr.push_back(1.0);
arr.push_back(2.0);
arr.push_back(3.0);
arr.push_back(1.0);
arr.push_back(2.0);
minimaxsum(arr);
return 0;
}

There are 2 problems.
Your code is unfortunately buggy and cannot deliver the correct result.
The solution approach, the design is wrong
I will show you what is wrong and how it could be refactored.
But first and most important: Before you start coding, you need to think. At least 1 day. After that, take a piece of paper and sketch your solution idea. Refactor this idea several times, which will take a complete additional day.
Then, start to write your code. This will take 3 minutes and if you do it with high quality, then it takes 10 minutes.
Let us look first at you code. I will add comments in the source code to indicate some of the problems. Please see:
#include <iostream>
#include <vector>
#include <limits.h> // Do not use .h include files from C-language. Use limits
using namespace std; // Never open the complete std-namepsace. Use fully qualified names
void minimaxsum(vector<int> arr) { // Pass per reference and not per value to avoid copies
int i, j, temp; // Always define variables when you need them, not before. Always initialize
int n = sizeof(arr); // This will not work. You mean "arr.size();"
int sum = 0;
int low = INT_MAX; // Use numeric_limits from C++
int high = 0; // Initialize with MIN value. Otherwise it will fail for negative integers
for (j = 0; j < n; j++) { // It is not understandable, why you use a nested loop, using the same parameters
for (i = 0; i < n; i++) { // Outside sum should be calculated only once
sum += arr[i]; // You will sum up always. Sum is never reset
}
temp = sum - arr[j];
if (temp < low) {
low = temp;
}
else if (temp > high) {
high = temp;
}
}
cout << low; // You miss a '\n' at the end
cout << high << endl; // endl is not necessary for cout. '\n' is sufficent
}
int main() {
vector<int> arr; // use an initializer list
arr.push_back(1.0); // Do not push back doubles into an integer vector
arr.push_back(2.0);
arr.push_back(3.0);
arr.push_back(1.0);
arr.push_back(2.0);
minimaxsum(arr);
return 0;
}
Basically your idea to subtract only one value from the overall sum is correct. But there is not need to calculate the overall sum all the time.
Refactoring your code to a working, but still not an optimal C++ solution could look like:
#include <iostream>
#include <vector>
#include <limits>
// Function to show the min and max sum from 4 out of 5 values
void minimaxsum(std::vector<int>& arr) {
// Initialize the resulting values in a way, the the first comparison will always be true
int low = std::numeric_limits<int>::max();
int high = std::numeric_limits<int>::min();;
// Calculate the sum of all 5 values
int sumOf5 = 0;
for (const int i : arr)
sumOf5 += i;
// Now subtract one value from the sum of 5
for (const int i : arr) {
if (sumOf5 - i < low) // Check for new min
low = sumOf5 - i;
if (sumOf5 - i > high) // Check for new max
high = sumOf5 - i;
}
std::cout << "Min: " << low << "\tMax: " << high << '\n';
}
int main() {
std::vector<int> arr{ 1,2,3,1,2 }; // The test Data
minimaxsum(arr); // Show min and max result
}

Related

Hey, I am trying to submit the source code of codechef sept challange Q code - "MNDIGSM2". But it reject my answer as "Runtime error"

When i run the source code on sample cases of their example it runs fine but when I submit the question It says runtime error.
Here is my Source code and link of the question.
Question link - https://www.codechef.com/SEPT21C/submit/MNDIGSM2
Below is the code.
#include <iostream>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;
// #define fast ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int converter(int n , int b){
vector<int> vec;
int sum = 0;
while(n>0){
vec.push_back(n%b);
n = n / b;
}
int vecSize = vec.size();
for(int i = 0;i<vecSize;i++){
// cout<<
sum = sum + vec[i];
}
return sum;
}
int minVal(vector<int> arr , int len){
int min = arr[0], c = 0;
// if(arr)
for(int i = 1 ; i< len;i++){
if (arr[i] < min){
min = arr[i];
c = i;
}
}
return c;
}
int main() {
// your code goes here
// fast;
int test;
cin>>test;
while(test--){
int n ,r;
cin>>n>>r;
int l = 2;
// ll copy = l;
int arSize = (r-2)+1;
vector<int> arr(arSize);
for(int i = 0;i< arSize ;i++){
arr[i] = converter(n,l);
l++;
}
int tobe = minVal(arr , arSize);
cout<<tobe + 2<<endl;
}
return 0;
}
Maybe I do not understand the question fully. There is not enough information available.
It could be that the program slows down because the usage of the std::vector. First you calculate, then store the values and then iterate again over all values.
This is not necessary. You can do all calculations inline without the need for additional storage.
And, additionally, all these "contest" questions do not have the intention, to improve your programming skills.
Basically the language doesn't matter. The important thing is the algorithm. They want you to find a "good" algorithm.
Bruteforcing is nearly never a feasible solution. If you read about big numbers like 10^12, then you know already in advance that you will get a TLE with the brute force solution.
Regarding this horrible and non compliant C++ slang that is used on this "competetion" sides, please note that this is nearly never necessary. You have no time contraints to submit a solution. So, you could use also real C++ code.
Anyway. I corrected your code and added meaningful varibale names, comments and formatting. So, logically, the approach is the same, but it is readable.
Of course it may fail as well, because it is still brute forcing . . .
#include <iostream>
#include <limits>
constexpr unsigned long long BaseStart = 2ull;
int main() {
// Get number of test cases
unsigned int numberOfTestCases{};
std::cin >> numberOfTestCases;
// Work on all test cases
for (unsigned int testCase{}; testCase < numberOfTestCases; ++testCase) {
// Get the value to check and the upper limit for the base
unsigned long long valueToCheck{}, upperLimitBase{};
std::cin >> valueToCheck >> upperLimitBase;
// Here we will store the minimum sum to check
unsigned long long minimumsumOfDigits{std::numeric_limits<unsigned long long>::max()};
// Here we will store the result
unsigned long long minimumBase{};
for (unsigned long long base{BaseStart}; base <= upperLimitBase; ++base) {
// And this will be the running sumOfDigits
unsigned long long runningSumOfDigits{};
// get the digits of the value and calculate the running sum
unsigned long long value{valueToCheck};
while (value > 0) {
// Get digits via modulo division and add up
runningSumOfDigits += value % base;
value /= base;
}
// Get current minimum
if (runningSumOfDigits < minimumsumOfDigits) {
minimumsumOfDigits = runningSumOfDigits;
minimumBase = base;
}
}
std::cout << minimumBase << '\n';
}
return 0;
}
This code can of course be optimized further, but for this I would need more information . . .

Why doesn't my recursive longest increasing subsequence function work for large inputs?

I wrote it to work on a single test case at a time.
It either takes too long on online judges or returns wrong answers
Source: The problem I used to test it on
It works perfectly for small cases:
#include <iostream>
#include <algorithm>
#include <vector>
int LIS[100000];
void LS (int *arr , int n)
{
if (n == 0)
{
LIS[0] = 1;
return;
}
if (LIS[n])
{
return;
}
int i = 0;
int max = 0;
while (i < n)
{
if (arr[i] < arr[n])
{
LS(arr,i);
if (LIS[i] + 1 > max)
{
max = 1 + LIS[i];
}
}
++i;
}
LIS[n] = max;
}
int main()
{
int n;
std::cin >> n;
int arr[n];
for(int i = 0 ; i < n ; ++i) std::cin >> arr[i];
LS(arr,n-1);
std::sort (LIS , LIS+n);
std::cout << "\n" << LIS[n-1] << "\n";
}
You said it works perfectly small cases.. than maybe it is stack overflow..
A function call consume stack memory..
If recursive call depth is too deep, stack memory runs out, and crash..
When you read int n value from std::cin, you have to dynamically allocate memory for your array arr, so you should first declare int *arr, then get the user input the same way as you're doing it now, and then allocate memory using arr = new int[n].
When it comes to the long time it takes to compute next values using recursive function, you should think about remaking the function to use tail recursion, which is much closer to iteration. You can check the difference by writing two programs for counting Fibonacci numbers - one recursive and another one iterative, then check how long it takes to compute ~50th value using both methods.

Finding minimum and maximum in a array c++

I have to find the minimum and maximum value of elements in a array using divide and conquer. I have written a code but it is not working for more then 6 elements in array. I don't know whats the problem
#include<iostream>
using namespace std;
int minimum=999,maximum,mi,ma;
void result(int mi,int ma)
{
if(maximum<ma)
{
maximum=ma;
}
if(minimum>mi)
{
minimum=mi;
}
}
void maxmin(int arr[],int i,int j)
{
cout<<" i ="<<i<<" j= "<<j<<endl;
if(i==j)
{
mi=ma=arr[i];
result(mi,ma);
}
else if(i==j-1)
{
if(arr[i]>arr[j])
{
ma=arr[i];
mi=arr[j];
}
else
{
mi=arr[i];
ma=arr[j];
}
result(mi,ma);
}
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
}
int main()
{
int arr[10],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
maxmin(arr,0,n-1);
cout<<" max "<<maximum<<" min "<<minimum<<endl;
return 0;
}
Your code has a few mistakes
Your code reads n from the user input, but you provided only 10 sized array, and user can try to input 10+ numbers, so we will have an undefined behavior in that case.
You write it very bad and unreadable. If you want somebody else to read your code, check in the your favourite book or in the internet information about how to write beautiful and readable code.
You implemented that algorithm yourself. It is a bad habit, use the standard library algorithms and you will not encounter such mistake.
.
#include <iostream> // std::cin, std::cout
#include <cstddef> // std::size_t
#include <algorithm> // std::min_element, std::max_element
int main ()
{
std::size_t array_size;
std::cin >> array_size;
int *some_array = new int[array_size]; // Allocate memory dynamically
for(std::size_t i = 0; i < array_size; ++i)
{
std::cin >> some_array[i];
}
/* Standard library operate on iterators, they are special classes
* that have interface that is similar in many cases to pointers (so we can use pointers as iterators).
* std::min/max_element needs one iterator for the sequence beginning
* and one iterator after the end. It returns iterator to a found element.
*/
int min = *std::min_element(some_array, some_array + array_size);
int max = *std::max_element(some_array, some_array + array_size);
delete[] some_array;
std::cout << "Min = " << min << std::endl << "Max = " << max;
std::cout << std::endl;
}
Code isn't well written and first dry run your code, you will find the problem easily.
Change
else
{
int mid=i+j/2;
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
To
else
{
int mid=(i+j)/2; /*** Adding brackets ***/
maxmin(arr,i,mid);
maxmin(arr,mid+1,j);
}
And check the logic for calling the result function (because according to your logic the two subsets are individually calculating MIN and MAX in itself not in whole array)

Coin Change DP Algorithm Print All Combinations

The classic coin change problem is well described here: http://www.algorithmist.com/index.php/Coin_Change
Here I want to not only know how many combinations there are, but also print out all of them. I'm using the same DP algorithm in that link in my implementation but instead of recording how many combinations in the DP table for DP[i][j] = count, I store the combinations in the table. So I'm using a 3D vector for this DP table.
I tried to improve my implementation noticing that when looking up the table, only information from last row is needed, so I don't really need to always store the entire table.
However my improved DP solution still seems quite slow, so I'm wondering if there's some problem in my implementation below or there can be more optimization. Thanks!
You can run the code directly:
#include <iostream>
#include <stdlib.h>
#include <iomanip>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, const char * argv[]) {
int total = 10; //total amount
//available coin values, always include 0 coin value
vector<int> values = {0, 5, 2, 1};
sort(values.begin(), values.end()); //I want smaller coins used first in the result
vector<vector<vector<int>>> empty(total+1); //just for clearing purpose
vector<vector<vector<int>>> lastRow(total+1);
vector<vector<vector<int>>> curRow(total+1);
for(int i=0; i<values.size(); i++) {
for(int curSum=0; curSum<=total; curSum++){
if(curSum==0) {
//there's one combination using no coins
curRow[curSum].push_back(vector<int> {});
}else if(i==0) {
//zero combination because can't use coin with value zero
}else if(values[i]>curSum){
//can't use current coin cause it's too big,
//so total combination for current sum is the same without using it
curRow[curSum] = lastRow[curSum];
}else{
//not using current coin
curRow[curSum] = lastRow[curSum];
vector<vector<int>> useCurCoin = curRow[curSum-values[i]];
//using current coin
for(int k=0; k<useCurCoin.size(); k++){
useCurCoin[k].push_back(values[i]);
curRow[curSum].push_back(useCurCoin[k]);
}
}
}
lastRow = curRow;
curRow = empty;
}
cout<<"Total number of combinations: "<<lastRow.back().size()<<endl;
for (int i=0; i<lastRow.back().size(); i++) {
for (int j=0; j<lastRow.back()[i].size(); j++) {
if(j!=0)
cout<<" ";
cout<<lastRow.back()[i][j];
}
cout<<endl;
}
return 0;
}
It seems that you copy too many vectors: at least the last else can be rewritten as
// not using current coin
curRow[curSum] = lastRow[curSum];
const vector<vector<int>>& useCurCoin = curRow[curSum - values[i]]; // one less copy here
// using current coin
for(int k = 0; k != useCurCoin.size(); k++){
curRow[curSum].push_back(useCurCoin[k]);
curRow[curSum].back().push_back(values[i]); // one less copy here too.
}
Even if it is readable to clean curRow = empty;, that may create allocation.
Better to create a function
void Clean(vector<vector<vector<int>>>& vecs)
{
for (auto& v : vecs) {
v.clear();
}
}

display 25 randomnumbers from an array

I have in C++ an array of 100 elements, so v[1], ... ,v[100] contains numbers. How can i display, 25 random numbers from this array? So i wanna select 25 random positions from this array and display the values.. How can i do this in C++?
Thanks!
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
using namespace std;
int aleator(int n)
{
return (rand()%n)+1;
}
int main()
{
int r;
int indexes[100]={0};
// const int size=100;
//int a[size];
std::vector<int>v;
srand(time(0));
for (int i=0;i<25;i++)
{
int index = aleator(100);
if (indexes[index] != 0)
{
// try again
i--;
continue;
}
indexes[index] = 1;
cout << v[index] ;
}
cout<<" "<<endl;
system("pause");
return 0;
}
The idea is that i have this code, and i generate 100 random numbers. What i want is an array with random 25 elements from those 100 generated.. But i don't know how to do that
Regards
Short Answer
Use std::random_shuffle(v.begin(),v.end()) to shuffle the array, and then display the first 25 elements.
Long Answer
First of all, the elements would be v[0]...v[99] (C++ uses 0-based indexing), not v[1]...v[100]. To answer your question, though, it depends on whether it is acceptable to repeat elements of the array or not. If you aren't worried about repeats, then simply use the index rand()%v.size(), repeatedly until you have selected a sufficient number of indices (25 in your question). If repeats are not acceptable, then you need to shuffle the array (by swapping elements at random), and then display the first (or last, or any contiguous region of) N elements (in this case N=25). You can use std::random_shuffle to shuffle the array. That does the bulk of the work for you. Once you've done that, just show 25 elements.
If you want to print 25 numbers of an array V you can use this code do:
int V[100]={1,2,5,...} ;
srand ( time (0) ) ;
for (int i=0;i<25;i++)
{
cout << V[rand() % 100 + 1]<<" " ;
}
I modified the version of Mehdi a little in order to make it choose differnet indexes
NOTE: This makes the algorithm not deterministic - it relies on the RNG.
int indexes[100]={0};
srand ( time (0) );
for (int i=0;i<25;i++)
{
int index = rand() % 100;
if (indexes[index] != 0)
{
// try again
i--;
continue;
}
indexes[index] = 1;
cout << v[index] ; cout << endl;
}