Climbing the leaderboard- hacker rank [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I was solving this problem in Hackerrank.
This question will give us an array of scores. We have to rank those sores as per the dense leader board ranking. It means the highest score gets the first rank, if the next score is equal to the highest rank, we give them the same rank. If it is less than that, we give it the next immediate rank.
ex- the scores 100, 80, 80, 60 will get ranks 1, 2,2 3.
ALso we are given an array of alice's score and we have to find out what rank Alice will get with each of her score.
Note that the scores are given in descending order. And Alice's scores are given in ascending order.
WHat I do is first create an array whoose ith element will denote the rank of ith score in the score vector.
Then I take the smallest score of ALice and do a search of the smallest score >= Alice's score. Then I gave ALice's score the rank accordingly. AFter that I pick the second smallest alice score and this time start searching for the smallest score >= Alice's score from where I left off.
This is the code that I wrote-
#include <vector>
#include <iostream>
using namespace std;
//function for the question.
vector<int> climbingLeaderboard(vector<int> scores, vector<int> alice)
{
vector<int> rank; //another array that will store the rank of all people already on the leaderboard
vector<int> result; //vector that will store the return value of alice's rank.
int val = scores[0]; //stores the current score that we are pointing on.
int len = 1, k, n = 0; //len is the current rank we are on. it changes if value(score) changes.
for (int i = 0; i < scores.size(); i++) {
if (scores[i] == val) { //if the scores are equal...
rank.push_back(len); //it stores the value of len that is the rank. This command ensures that the same scores have the same rank.
}
else if (scores[i] < val) { //if the score is less than val....
len++; //increments len by 1.
rank.push_back(len); //gives the current len as rank to the next person.
val = scores[i]; //sets the new value to the current score
}
}
//now I have stored ranks. Now for giving alice ranks...
k = scores.size() - 1; //points to the current score that we are comparing for Alice.
for (int j = 0; j < alice.size(); j++) { //does the loop for every score of Alice given.
k = n; //sets k=n so that we begin our search with the same index we left on for the next time.
while (k >= 0) {
if (scores[k] < alice[j]) { //if score is less, sub 1 from k
k--;
}
else if (scores[k] == alice[j]) {
result[j] = rank[k]; //if scores are equal, we set the rank of alice same as that of the rank that this score got.
n = k; //we store the value of k for which the scores are equal.
k = -1; //to end the while loop
}
else if (scores[k] > alice[j]) {
result[j] = rank[k] - 1;
n = k; //we do the same if the scores are one less, but give one less rank
k = -1;
}
}
}
return result; //return the vector.
}
// main function just takes in all the values and prints the vector that we get
int main()
{
int n, value, m;
cin >> n;
vector<int> scores;
vector<int> alice;
for (int i = 0; i < n; i++) {
cin >> value;
scores.push_back(value);
}
cin >> m;
for (int i = 0; i < m; i++) {
cin >> value;
alice.push_back(value);
}
vector<int> result;
result = climbingLeaderboard(scores, alice);
for (int k = 0; k < m; k++) {
cout << result[k];
cout << endl;
}
return 0;
}
It is showing a runtime error. Pls look at the code and tell me whats wrong. Also I would suggest to look at the link once bcoz it will explain the question much better than I evr will.
It also contains the sample inputs and sample outputs. The input format is a bit strange.

Looking at the debug output it's clear that you have an out of bounds access on one of your vectors.
Looking at the code I can see at least one such problem (there may be more)
vector<int> result;
...
result[j]=rank[k];
...
result[j]=rank[k]-1;
result is a vector with size 0, at no point do you resize it. So result[j]=... is an out of bounds vector access.

Related

Need to find the minimum value of a 4x2 array while ignoring the diagonal

I need to find the lowest value in an array that isn't in the main diagonal, I have written some code but it seems to pick either the second or the last value only (depending on which one is the lowest).
here is my code:
#include<iostream>
using namespace std;
int main()
{
int arr[4][2];
int Min,i,j;
cout<<"Type 8 numbers";
for (i=0;i<4;i++)
{
for (j=0;j<2;j++)
{
cin>>arr[i][j];
Min=arr[0][1];
if(i!=j and Min > arr[i][j])
{
Min=arr[i][j];
}
}
}
cout<<"The values of the array are: \n";
for (i=0;i<4;i++)
{
cout<<"\n";
for (j=0;j<2;j++)
{
cout<<arr[i][j]<<"\t";
}
}
cout<<"The lowest value is: "<<Min;
}
If I type 1-8 the returned value is 2, if I type 8-1 the returned Value is 1, in both of these cases the code is working as I intended, but if I type something like 8,6,4,1,2,3,4,5, the lowest value is returned as 5, I'm very new to coding and would appreciate any help.
The line
Min=arr[0][1];
is bad because
It reads uninitialized arr[0][1] when i = 0, j = 0.
It writes arr[0][1] to Min unconditionally, even if current Min is smaller than that.
Instead of this:
Min=arr[0][1];
if(i!=j and Min > arr[i][j])
{
Min=arr[i][j];
}
This will work, for example:
if(i!=j and ((i==0 and j==1) or Min > arr[i][j]))
{
Min=arr[i][j];
}
Your Min=arr[0][1] line is inside both loops, which means each time when you are trying to compare Min and the current element arr[i][j], you just threw away whatever smallest value stored in Min and replaced it with arr[0][1].
Hence the code as you have written returns either the last number or arr[0][1], whichever is smaller.
You should really only initialise this Min once before your loops begin. i.e.
Min = arr[0][1]
for(i = 0; i < 4;i++)
{
for(j = 0; j < 2; j++)
{
// Compare Min and arr[i][j] and reassign the smaller one to Min if i != j
}
}

Sorting a vector in descending order and adding from the front works, but sorting in ascending order and adding from the back doesn't?

I'm attempting a problem on codeforces. The gist of the question: There are n days, and on each day there are k products up for sale and l customers visiting. Each customer will either purchase one product or if there aren't any left, leave without buying anything. Any excess unpurchased product is thrown away. In order to maximise the number of products sold, you choose any f days from n and double the number of products put up for sale. Find the maximal number of products you can sell.
So my approach was to calculate min(2k, l) - min(k, l) for each of the days and store it in a vector v. I sort this vector and sum up the largest f of these values. Then, I sum up min(k, l) for every single day, and adding it to the previous sum I get my answer.
The problem is: When I do sort(v.rbegin(), v.rend()) and add the first f elements, I get the right answer. However, when I do sort(v.begin(), v.end()) and add the elements from index int i = v.size() - 1; i > v.size() - 1 - f; i-- aka the last f elements, I fail on the 28th test case.
The ranges are 1 ≤ n ≤ 10^5, 0 ≤ f ≤ n and 0 ≤ k i, l i ≤ 10^9. I'm not sure if it's a case of overflow though I doubt it because I used long long to store my answer, and on the test case I failed the expected output is a small integer. Thanks for reading, hope someone could help me out on this
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n, f;
cin >> n >> f;
vector<int> v;
vector<int> v2;
for(int i = 0; i < n; i++)
{
int k, l;
cin >> k >> l;
int difference = min(2*k, l) - min(k, l);
v.push_back(difference);
v2.push_back(min(k, l));
}
sort(v.begin(), v.end());
long long ans = 0;
for(int i = v.size()-1; i > v.size()-1-f; i--)
{
ans += v[i];
}
for(int i = 0; i < v2.size(); i++)
{
ans += v2[i];
}
cout << ans << endl;
}

Incorrect output for the second smallest integer

I'm having trouble finding the second smallest integer in my array. The array is unsorted (it's what's in the data.txt file), so I know that might be part of the problem, I'm not sure how to fix this in the simplest way. Afterwards I have to remove that integer from the array, move every number over and reprint the array, if anyone could help I'd really appreciate it.
const NUM = 10;
int Array[NUM];
ifstream infile;
infile.open("Data.txt");
for (int i = 0; i < NUM; i++)
{
infile >> Array[i];
cout << Array[i] << endl;
}
int Min = Array[0];
int Next = 0, SecondMin = 0;
for (int k = 0; k < NUM; k++)
{
if (Min > Array[k])
Min = Array[k];
}
for (int m = 2; m < NUM; m++)
{
Next = Array[m];
if (Next > Min)
{
SecondMin = Min;
Min = Next;
}
else if (Next < SecondMin)
{
SecondMin = Next;
}
}
cout << "The second smallest integer is: " << SecondMin << endl;
You don't have to loop over the array twice to find the second smallest number. As long as you're keeping track of both the smallest and the second smallest, you should be able to find them both with a single loop.
There are a couple of other problems with this code:
Your check for end of file should probably be if (!infile.eof())
You don't need to check if (i < NUM) inside your loop. i will always be less than NUM due to the constraint on the loop.
If for some reason the number of items in the file is less than NUM, the rest of the items in the array will have undefined values. For instance, if there were only nine items in the file, after reading the file, Array[9] would have whatever value happened to be in that spot in memory when the array was created. This could cause problems with your algorithm.
I assume that this is some sort of homework problem, which is why the use of an array is required. But keep in mind for the future that you'd probably want to use a std::vector in this sort of situation. That way you could just keep reading numbers from the file and adding them to the vector until you reached the end, rather than having a fixed number of inputs, and all of the values in the vector would be valid.

Distinct numbers in array

I have no idea what to do. Please help me with code or tell me what textbook to look up or something; I need code to finish this program and I would love an explanation of what I'm looking at..
#include<iostream>
using namespace std;
int main()
{
short num[100], size, //declare an array of type short that has 100 elements
unique[100], number, // declare a second array to help solve the problem; number counts the number of unique values
k; // loop control variable; may need other variables
cout<<"enter the number of values to store in the array\n";
cin>>size;
cout<<”enter the “<<size<<” values to be used as data for this program\n”;
for(k=0; k<size; k++)
cin>>num[k];
// print the contents of the array
cout<<"\nthere are "<<size<<" values in the array\n";
for(k=0; k<size; k++)
cout<<num[k]<<’ ‘; // there is one space between each number in the display
cout<<endl; // cursor moved to next output line
cout<<"the program will count the number of different (distinct) values found in the array\n";
//************************************************************
//Put the code here that counts the number of unique values stored in the
//array num. The variable number will contain the count.
//************************************************************
cout<<endl<<number<<" unique values were found in the "<<size<<" element array\n";
// pause the program to see the results
system("pause");
//return 0;
}
I have to do one of these two things and I don't know what they mean?
Algorithm – unique array is used to help find the solution, used to avoid counting any value more than one time
Set number to 0 - this represents the number of distinct values in the data set; also used as a subscript in the unique array
Loop from 0 to size by one, proceeding through successive elements of the data (num) array
Store value of current array element in non-array variable (SV)
Set event_flag to 0
Loop from 0 to number by one, proceeding through successive elements of unique array
If SV is equal to current element of unique array
Set event_flag to 1
Break (stop) inner loop
End of inner loop
If event_flag is equal to 0 (value not found in unique array and not previously counted)
Store SV in element number of unique array
Increment the value of number
End of outer loop
Solution – the variable number contains the count of distinct values in the data array
Alternate Algorithm
Algorithm that does not use the event_flag (loop control variable can be used to determine if event occurred)
Algorithm – unique array is used to help find the solution, used to avoid counting any value more than one time
Set number to 0 - this represents the number of distinct values in the data set; also used as a subscript in the unique array
Loop from 0 to size by one, proceeding through successive elements of the data (num) array
Store value of current array element in non-array variable (SV)
Loop from 0 to number by one, proceeding through successive elements of unique array
If SV is equal to current element of unique array
Break (stop) inner loop
End of inner loop
If loop control variable of inner loop is equal to value of number (SV not found in unique array and not previously counted)
Store SV in element number of unique array
Increment the value of number
End of outer loop
Solution – the variable number contains the count of distinct values in the data array
I put this in mine:
//************************************************************
//Put the code here that counts the number of unique values stored in the array num. The variable number will contain the count.
for(k=0; k<size; k++)
num=SV;
event_flag=0;
for(k=1; k<number; k++)
if(SV=unique)
return true;
return false;
//************************************************************
It's not working, obviously.
This is my code, it seems to work
//************************************************************
//Put the code here that counts the number of unique values
//stored in the array num. The variable number will contain the count.
number = 0;
for (k = 0; k < size; ++k)
{
short sv = num[k];
short event_flag = 0;
for (int i = 0; i < number; ++i)
{
if (sv == unique[i])
{
event_flag = 1;
break;
}
}
if (event_flag == 0)
{
unique[number] = sv;
++number;
}
}
For the alternative ,
his is my code, it seems to work
//************************************************************
//Put the code here that counts the number of unique values
//stored in the array num. The variable number will contain the count.
number = 0;
for (k = 0; k < size; ++k)
{
short sv = num[k];
int i;
for (i = 0; i < number; ++i)
if (sv == unique[i])
break;
if (number == i)
{
unique[number] = sv;
++number;
}
}
You are roughly asked to do the following:
#include <iostream>
using namespace std;
int main()
{
// This is the given array.
int given_array[5] = { 1, 1, 2, 2, 3 };
// This is the array where unique values will be stored.
int unique_array[5];
// This index is used to keep track of the size
// (different from capacity) of unique_array.
int unique_index = 0;
// This is used to determine whether we can
// insert an element into unique_array or not.
bool can_insert;
// This loop traverses given_array.
for (int i = 0; i < 5; ++i)
{
// Initially assume that we can insert elements
// into unique_array, unless told otherwise.
can_insert = true;
// This loop traverses unique_array.
for (int j = 0; j < unique_index; ++j)
{
// If the element is already in unique_array,
// then don't insert it again.
if (unique_array[j] == given_array[i])
{
can_insert = false;
break;
}
}
// This is the actual inserting.
if (can_insert)
{
unique_array[unique_index] = given_array[i];
unique_index++;
}
}
// Tell us how many elements are unique.
cout << unique_index;
return 0;
}
Try out this one...
You can insert cout statements wherever required.
#include <iostream>
using namespace std;
int main()
{
int Input[100], Unique[100], InSize, UniLength = 0;
cin >> InSize;
for (int ii = 0 ; ii < InSize ; ii++ )
{
cin >> Input[ii];
}
Unique[0] = Input[0];
UniLength++;
bool IsUnique;
for ( int ii = 1 ; ii < InSize ; ii++ )
{
IsUnique=true;
for (int jj = 0 ; jj < UniLength ; jj++ )
{
if ( Input[ii] == Unique[jj] )
{
IsUnique=false;
break;
}
}
if ( IsUnique )
{
Unique[UniLength] = Input[ii];
UniLength++;
}
}
cout<<"We've "<<UniLength<<" Unique elements and We're printing them"<<endl;
for ( int jj = 0 ; jj < UniLength ; jj++ )
{
cout << Unique[jj] << " ";
}
}
I hope this is what you were looking for.....
Have a nice day.
Here is my approach. Hope so it will helpful.
#include<iostream>
#include<algorithm>
int main(){
int arr[] = {3, 2, 3, 4, 1, 5, 5, 5};
int len = sizeof(arr) / sizeof(*arr); // Finding length of array
std::sort(arr, arr+len);
int unique_elements = std::unique(arr, arr+len) - arr;
std::cout << unique_elements << '\n'; // The output will 5
return 0;
}

Graphs and depth-first search using vectors in C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I saw the following code for making a graph and doing depth-first search on it. Can you explain me the use of vector g here. In the second function, how it is written as a 2-dimensional thing. Please explain the whole process clearly, on using vectors for this purpose. Problem is following:--- A Company is connected to n cities numbered from 1 to n. Currently the Headquarter of company is situated at index hq1. Each pair of connected cities are connected both ways. The connection is such that there is exactly one connection from the Headquarter to each city. The map of the connected cities is kept in the following way: for each city i, different from the Headquarter, there is kept number ci — index of the last city on the way from the Headquarter to i.
The company decided to move the Headquarter from city hq1 to city hq2. So, after this change the old representation of the map as described above became incorrect. Please, help the company to find out a new map in the way described above.
Input
The first line contains the number of test cases(0 < T <= 10 ). The next line contains three space-separated integers n, hq1, hq2 (2 ≤ n ≤ 2*10^4, 1 ≤ hq1 ≠ hq2 ≤ n) — number of connected cities, index of the old Headquarter and index of the new Headquarter, respectively.
The following line contains n - 1 space-separated integers — the old representation of the map. For each city, other than hq1, there is given integer ci — index of the last city on the way from the Headquarter to city i. All the cities are described in order of increasing indexes.
Output
Output n - 1 numbers — new representation of the map in the same format. The solution is given below.
vector < int >g[10005];
void make_graph()
{
int k = 1;
for (int i = 1; i <= n; i++)
{
if (i == h1)
continue;
int x;
cin >> x;
g[x].push_back (i);
g[i].push_back (x);
}
}
int visited[20004], parent[20004];
void dfs(int x)
{
visited[x] = 1;
for (int i = 0; i < g[x].size (); i++)
{
int j = g[x][i];
if (j == parent[x])
continue;
parent[j] = x;
dfs (j);
}
return;
}
int
main ()
{
int t;
cin >> t;
while (t--)
{
cin >> n >> h1 >> h2;
make_graph ();
dfs (h2);
for (int i = 1; i < n; i++)
{
if (i == h2)
continue;
cout << parent[i] << " ";
}
if (n != h2)
cout << parent[n] << endl;
else
cout << endl;
memset (parent, 0, sizeof (parent));
memset (visited, 0, sizeof (parent));
for (int i = 1; i <= n; i++)
g[i].clear ();
}
return 0;
}
Vectors can be accessed via [] as normal arrays. g is an array of vectors of ints, so can be accessed as 2D array. It contains info about edges in graph of cities, as an adjacency list
In make_graph() on list (vector) of x'th vertex, i'th one is pushed and vice versa, because the connection is in both ways.
In dfs() function for each adjacent vertex j on x'th list, x is marked as j's parent, because DFS starts from root (new HQ) and x is connected with j.
Line if (j == parent[x]) prevents from DFS-ing parent nodes (which still are on their children's lists).