Wrong number of iterations in for loop.Also getting unexpected output - c++

Codeforces problem 160A-http://codeforces.com/problemset/problem/160/A
I am getting either 1 or 2 as the output for all test cases.I think this is because the for loop at the end of the solution is only running either once or twice only.I am not able to identify why is the loop ending after atmost 2 iterations.What is wrong with my solution.
My solution:
#include<iostream>
using namespace std;
int total(int x,int y,int array[100]) //Function to calculate sum of xth to yth term of array.
{
int z=0;
for(int a=x;a<=y;a++)
{
z+=array[a];
}
return z;
}
int main()
{
int n,coin[],sum1,sum2,i,j,a,temp,noofcoins;
cin>>n;
for(i=0;i<n;i++)
cin>>coin[i];
for(i=0;i<n;i++) //Bubble sorting array in descending order.
{
for(j=0;j<n-i-1;j++)
{
if(coin[j]<coin[j+1])
{
temp=coin[j];
coin[j]=coin[j+1];
coin[j+1]=temp;
}
}
}
noofcoins=0;
sum1=0;
sum2=0;
for(i=0;((i<n)&&(sum1<=sum2));i++)
{
sum1+=coin[i];
sum2=total(i+1,n,coin);
++noofcoins;
}
cout<<noofcoins;
}

First, avoid using global variables. This declaration belongs to the main body
int n,coin[100],sum1,sum2,i,j,temp,noofcoins;
Once you correct it you'll notice the variable i used in the function totalis the same as the one used in main. Just initialize it in the for.
for(int i=x;i<y;i++)
Then, the condition in the final for is wrong. It should be:
for(i=0;((i<n)&&(sum1<=sum2));i++)

You have defined i as a global variable.
You use i both in the function total as in main where you use i for the loop where you call total. So after you called total, i has become a different value, and the loop in main will end.

U have declared i as a global variable and then u are using it at two places and then that's certainly causing the problems

1-there's no reason to declare your variables globally, it's better to declare them in your main() function.
2-Your way of bubble sorting seems to be wrong. The correct way is to sort the bubble until there's no swapping required.
bool flag=flase;
while (!flag){
flag=true;
for(i=0;i<n-1;i++){ //Bubble sorting array in descending order.
if (coin[i]<coin[i+1]){
temp=coin[i];
coin[i]=coin[i+1];
coin[i+1]=temp;
flag=false;
}
}
}
3-your way of passing an array to a function is incorrect. Read the part "Arrays as parameters" on this page for the right way.
4-Finally, you might want to use "new" function to create your array. This way it will not be limited to your maximum array size of 100, and also won't waste memory when your array is smaller than 100.
Read here for learning to use "new" function.

following may help:
int twin(std::vector<int> coins)
{
std::sort(coins.begin(), coins.end());
const int total = std::accumulate(coins.begin(), coins.end(), 0);
int left = total;
int right = 0;
for (size_t i = 0; i != coins.size(); ++i)
{
const int value = coins[coins.size() - 1 - i];
left -= value;
right += value;
if (right > left) {
return 1 + i;
}
}
return 0;
}

Related

I tried to find the location of the array's element, but the professor said it was wrong

int search( int arr[], int size, int num) {
int i, loc;
loc=i;
for (i=0;i<size;i++){
if (arr[i]==num)
return loc;
else
return -1;
}
}
can someone tell me where did I go wrong?
There are several problems with the shown code as described below.
Problem 1
The variables i and loc are uninitialized and using those uninitialized variables(which you did when you wrote loc = i) is undefined behavior.
Problem 2
The logic that you've used for the for loop and also for the if else part is not correctly implemented. In particular, suppose the for loop is not entered due to the condition i<size being false, then no return statement will be encountered for your non-void returning function again leading to undefined behavior.
Solution
There is no need to create a variable named loc. You can just directly return i when the element is found. Moreover there is no need for the else block. If the element is not found while iterating through the elements, we just return -1 after the for loop.
int search( int arr[], int size, int num) {
for (int i=0; i < size; i++)
{
if (arr[i]==num)
return i;//value found so return i directly
}
return -1; //value was never found
}
int main()
{
int arr[] = {1,2,33,54,3};
std::cout<<search(arr, 5, 3)<<std::endl; //prints 4
std::cout<<search(arr, 5, 33)<<std::endl; //prints 2
std::cout<<search(arr, 5, 98)<<std::endl; //prints -1
}
Working demo.
Here is a solution that resolves the issues in your initial code. Let's break it down by commenting the code.
int search(int arr[], int size, int num) {
// Initialize `location` to a value, this is very important
// In this case, it's okay to initialize to the "not found"
// value and you can simply `return location` at the end of
// this function.
int location = -1;
for (int index = 0; index < size; index++) {
// Check to see if `arr[index] == num`
// If so, we found `num` in `arr` !
// Otherwise, let the loop continue
if (arr[index] == num) {
// Since we found `num` in `arr`, let's store the index
// by updating our location
location = index;
// We found the index we are looking for
// No need to continue the `for` loop
break;
}
// No need for an `else` here, as it was noted in comments that
// returning in the `else` block would exit your loop early
}
// Just return `location`. It either stores `-1` of the index of `num`
return location;
}
Take time to review your solution and compare it to this particular solution. The primary issues with your original code were
You didn't initialize the loc variable nor did you ever update it before returning. This results in Undefined Behavior.
You had an else statement that returned -1 inside your for loop, which resulted in the loop only ever iterating a single time
Note that there are several ways to write this function and I've just shown one approach. Consider how you could write something functionally equivalent using your own approach.
Also note that you could simplify this code to not use a location variable altogether, as in the answer provided by #AnoopRana. I've left the use of the location variable in my example since it seemed to be closer to what you were originally going for. This solution is verbose in an attempt to help you understand more thoroughly what the algorithm is doing.
#include <iostream>
int search(int arr[], int n , int element)
{
int i = 0;
while (i < n)
{
if (arr[i] == element) {
break;
}
i++;
}
if (i < n)
{
return i;
}
else {
return -1;
}
return 0;
}
int main()
{
int arr[] = { 1, 2, 33, 54, 98 };
int n = sizeof(arr)/sizeof(arr[0]);
int element;
std::cout<<"Enter element to search for ";
std::cin>>element;
std::cout<<search(arr,n,element);
}

the declare scope of loop

Can anyone explain to me, why the below codes have different output?
void GenerateMatrix(int mat[][MaxSize],int ran[],const int rows,const int cols)
{
int i,k=0;
while (i<rows)
{
int j=0;
while (j<cols)
{
mat[i][j]=ran[k];
j,k++;
}
i++;
}
}
and the correct one
void GenerateMatrix(int mat[][MaxSize],int ran[],const int rows,const int cols)
{
int k=0;
for (int i=0; i<rows;i++)
{
for (int j=0; j<cols;j++)
{
mat[i][j]=ran[k];
k++;
}
}
}
the ran[] is an array declared in main()
int main()
{
srand(time(NULL));
int a[10];
for (int i=0;i<10;i++)
{
a[i]={(rand() % 20-0+1)+1};
cout<<a[i]<<endl;
}
.
.
.
}
the first one always output strange random numbers, not in the range of random numbers I set for a[] in main().
The second one is correct.
I have change the scope of declaration of k in the first one function, still the same. I'm just wondering witch part result in this?
You seem to be following a "spoken English" approach to using the ,, like "do something to this list of variables". In this reading, the initialisation failure (where it does create a list other than you mean; spotted by CherryDT) and the incrementation failure (caused by misuse as comma operator; spotted by two commenters, including me) can be "read".
I propose to change that by reading up on the "comma operator" and reviewing some tutorials on other uses of ",".
Consider reducing/avoiding the use altogether, it is too dangerous for your coding habits.
In the first function you have two errors:
The statement
int i,k=0;
is equivalent to
int i;
int k=0;
This means that i is uninitialized and will have an indeterminate value.
You need to explicitly initialize it as well:
int i = 0, k = 0;
The second error is the statement:
j,k++;
This is equivalent to
j;
k++;
That is, it evaluates the left-hand side of the comma operator (i.e. j) and then throws away the result. Then it evaluates and returns the result of the right-hand side (i.e. k++).
You need to increment both variables:
j++;
k++;
Or you can use the for loops which are more compact, still as readable, and harder to make such mistakes as in the first function.

Find ways an Integer can be expressed as sum of n-th power of unique natural numbers.code giving wrong output

I have t test cases.
Given two numbers x and n, find number of ways x can be expressed as sum of n-th power of unique natural numbers.
The approach is to either select a number or move to the next one.The ans returned is stored in an array since I am using the dp approach.
This is my code
#include<bits/stdc++.h>
using namespace std;
int arr[101];
int func(int x,int n,int ind)
{
if(arr[x]!=-1)
{
return arr[x];
}
if(x==0)
{
return 1;
}
if(ind>=(sqrt(x)+1))
{
return 0;
}
if(x<0)
{
return 0;
}
//you can either take ind or just move to the next one
arr[x]=func(x-pow(ind,n),n,ind+1)+func(x,n,ind+1);
return arr[x];
}
int main()
{
int t;
cin>>t;
while(t)
{
int ans=0;
memset(arr,-1,sizeof(arr));
int x,n;
cin>>x>>n;
int ind=1;
ans=func(x,n,ind);
cout<<"printing the ans\n"<<ans;
t--;
}
return 0;
}
for input
1
10 2
I am getting
printing the ans
-297160607
though the ans is 1
I inserted a simple debug output in func. For the given input "1 10 2" x sometimes gets negative. This causes UB when accessing the array, but does not necessarily crash.
You already check if x is less than 0, but after using x. Move the if(x < 0) up and you are done.
In general to avoid such mistakes you should use stl containers like std::array or std::vector. Though it is not garantued by the c++ standard, many implementations will performe bounds checking on operator[] when compiled in debug mode. Or you can use at() where the standard garantuess bounds checking.

Sort Specific Column of 2D int array (C++)

I've got a bit of a conundrum. I'm currently trying to create a user-defined function to sort a column (in ascending order) of a 2D int array I created and populated in the main function. I feel like I'm close, but for some reason the final output is incorrect, it provides a number for the final value that isn't even in the array. Judging from the value provided and the extra few seconds it takes to compile, I'm assuming I've messed up my bounds/ gone beyond them at some point within the code, but I've been fighting this thing for hours to no avail and I feel fresh (and likely more experienced) eyes would be-be of some use. I'm still in my "Intro to" class for programming, so ripping me a new one for obvious errors is encouraged as my final is this Thursday and any and all pointers/tips are appreciated. Cheers!
#include <iostream>
using namespace std;
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
int userCol;
cout<<"Please enter the number of the column you'd like to sort: "<<endl;
cin>>userCol; //ask for appropriate column
for (int row_index=0; row_index<rows; row_index++) //start with first row and continue for all values in code
{
int temp;
if ((arr[row_index][userCol-1]<arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
}
}
for(int i=0; i<rows; i++)//print that shiz
{
for(int j=0; j<columns; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
int main()
{
const int rows = 3;
const int columns = 5;
int arr[rows][columns];
for (int row_index=0; row_index<rows; row_index++)
{
for (int column_index=0; column_index<columns; column_index++)
{
arr[row_index][column_index] = (50+rand()%51);
cout << arr[row_index][column_index]<<" ";
}
cout << endl;
}
findMaxandIndex(arr, rows, columns);//i left my code for this out because it's working and isn't utilized in the problem code
cout << endl;
sort2D(arr, rows, columns);
return 0;
Your sort function is very close to bubble sort, one of the simplest sorting algorithms to understand and implement. With a little modification, your code will work :
void sort2D(int arr[3][5], int rows, int columns) //the problem child
{
//input userCol ...
//sorting start here ...
bool found = true; //we can quit the loop if the array is already sorted.
for (int bubble = 0; bubble < rows-1 && found ; bubble++)
{
found = false;
for (int row_index=0; row_index < rows - bubble - 1; row_index++)
{
int temp;
if ((arr[row_index][userCol-1] < arr[row_index+1][userCol-1]))//if first value of selected column is less than next value
{
//swap two elements.
temp = arr[row_index+1][userCol-1];//create copy of second value
arr[row_index+1][userCol-1]=arr[row_index][userCol-1]; //replace second value with first value
arr[row_index][userCol-1]=temp;//set first equal to second's original value
found = true; //we found something, continue to sort.
}
}
}
//print out the result ...
}
As you start in C++, an advice is to use C++ facilities if possible : std::vector for your array and std::qsort for sorting elements.
Issue 1: The int arr[3][5]; you declared in sort2D() is NOT the same as the int arr[rows][columns]; you declared in main().
lesson : check (or web search) on "pass by reference" & "pass by value" . For simplicity, I recommend pass by value.
Issue 2: The sort only compare 2 values and only run for 1 pass.. so {2,1,4,3} may get sorted to {1,2,3,4} but {1,4,3,2} will only get to {1,3,2,4} with 1 pass. #ZDF comment is helpful for this part.
Issue 3: at this line.. temp = arr[row_index+1][userCol-1]; when row_index is 2, this will refer to a location that is not in the arr[][] array. arr are only defined for row = 0,1,2 .. not 3 (when row_index is 2, row_index+1 is 3). This may answer :
it provides a number for the final value that isn't even in the array.
Solution.. hurm. I suggest you have a look and try.. and share where you stuck at. you may also test the sort2D in the main function before doing it as separate function. IMHO, you can start by 1st looking for the sorting algorithm that works (with sample data).. Then work on making it work in this project. ( :
p/s: I don't see my post as an answer.. more like a correction guide.

IntSetArray implementation in c++

i have trying to imlement IntSetArray in c++ it compiles fine but result is wrong first 300 is ok and other numbers are below zero something very strange numbers .e.g -8231313 something like this)
what is wrong? it is code
#include <iostream>
using namespace std;
int quantity=10;
class Set
{
private :
int n,*x;
public:
Set(int maxval){
x=new int[quantity+1];
n=0;
x[0]=maxval;
}
int size(){ return n;}
void insert(int t){
for (int i=0;x[i]<t;i++)
{
if (x[i]==t)
return ;
for (int j=n;j>=i;j--)
x[j+1]=x[j];
x[i]=t;
}
n++;
}
void display()
{
for (int i=0;i<n;i++){
cout<<x[i]<<" "<<"\n";
}
}
};
int main(){
Set s(300);
s.insert(123);
s.insert(45);
s.insert(89);
s.insert(50);
s.insert(13);
s.insert(19);
s.display();
return 0;
}
Think through what happens the first time you try to insert something. x[0] contains 300 and t, what you are trying to insert, is 123.
The first statement in the insert method is this:
for (int i=0;x[i]<t;i++)
This for loop increments i while the ith element of x is less than t. But the 0th element of x is 300, which is not less than 123, so the loop never executes at all. Since in the constructor you only initialized the first element of x, the remainder have garbage values which are never changed.
I think that you most likely don't want the second loop to be inside the first loop anyway. What it seems that you are trying to do with the outer loop is find the first position in x where the value is greater or equal to t, and then the inner loop shifts everything down and inserts t. Then what you should be doing is this:
void insert(int t){
int i; // Declare this outside the first loop so that it
// remains accessible afterwords
for (i=0;x[i]<t;i++)
{
// Do nothing; the whole point is to increment i
}
// Now i contains the first index of x where x[i] >= t
// So now do the shift and insert:
if (x[i]==t)
return ;
for (int j=n;j>=i;j--)
x[j+1]=x[j];
x[i]=t;
n++;
}
A different, and potentially easier to understand, way to write this:
int i;
for (i=0;x[i]<t;i++)
{
// Do nothing; the whole point is to increment i
}
Is this:
int i = 0;
while (x[i] < t) ++i;
Why not use a std::set<int>?