I know, there are a lot of questions like this, but I want to see other's solutions only after solving this (https://www.hackerrank.com/challenges/climbing-the-leaderboard/problem). Here's my code:
vector<int> climbingLeaderboard(vector<int> ranked, vector<int> player) {
vector<int> ranked_new; // the same ranked but without repeating numbers
vector<int> ans; // vector with places
// filling ranked_new
for (int i = 1; i < ranked.size(); i++)
{ if (ranked[i] != ranked[i - 1]) ranked_new.push_back(ranked[i]); }
ranked_new.insert(ranked_new.begin(), ranked[0]);
int left = 0, right = ranked_new.size() - 1, mid;
bool flag;
// binary searching for place for every Alice's result
for (int i = 0; i < player.size(); i++)
{
flag = false; left = 0; right = ranked_new.size() - 1;
while (!(flag))
{
if (player[i] >= ranked_new[0]) { flag = true; ans.push_back(0); }
else if (player[i] <= ranked_new[ranked_new.size() - 1]) { flag = true; ans.push_back(ranked_new.size()); }
else
{
mid = (left + right) / 2;
if (left >= right) { flag = true; ans.push_back(left); }
else if (player[i] > ranked_new[mid]) { right = mid - 1; }
else { left = mid + 1; }
}
}
}
// increasing every ans element by one
for(int i = 0; i < ans.size(); i++) { ans[i]++; }
return ans;
}
It passed 0, 5, 8 and 11 tests. In tests which it didn't pass repeats one error. For example, in test 1:
88
88
87
85
84
84
83
82
but my code returns
88
88
88
85
84
84
82
82
This is the only bug, I think it's somewhere in binary search but I still can't understand how to fix it. Please can you give me a hint?
EDIT: here are my attempts
In controversial situations (like player[i] == ranked_new[some_index]) program disbehaves (for example in test 1 when it gives 88 88 88 instead of 88 88 87). So I thought I should edit the string
if (left >= right) { flag = true; ans.push_back(left); }
with this code
if (left >= right)
{
if (player[i] > left) {flag = true; ans.push_back(left - 1);}
else if (player[i] < left) {flag = true; ans.push_back(left + 1);}
else {flag = true; ans.push_back(left);
}
But I was wrong and it didn't work. Sample test case output: 6 4 2 1. My output: 6 3 1 1 (I tried to change left with right, swap them, swapped + and -, changed numbers but it works only if it pushes back "left" in any case). I have chosen 1 case when it outputs 6 5 3 1, changed code, set left to 1, etc. to decrement numbers between 6 and 1 but it still didn't work on the same tests. I thought about it for 1,5 days and then came to stackoverflow
Related
I was trying this problem - Minimum Cost Path.
I have solved the problem using Dijkstra's Shortest Path Algorithm. But when i tried this using recursion+memoisation i.e. using dynamic programming, i got stuck and could not debug my code. I need help as to where my code is wrong!!
I am really glad for the help.
#include<bits/stdc++.h>
using namespace std;
int n;
int a[105][105], dp[105][105];
int dfs(int x, int y){
if(x < 0 || y < 0 || x >= n || y >= n){
return INT_MAX;
}
if(x == 0 && y== 0){
return a[0][0];
}
if(dp[x][y] != -1){
return dp[x][y];
}
dp[x][y] = a[x][y] + min(dfs(x-1, y), min(dfs(x, y-1), min(dfs(x+1, y), dfs(x, y+1))));
return dp[x][y];
}
int main(){
int tt;
cin >> tt;
while(tt--){
int n;
cin >> n;
for(int i = 0 ; i < n; i++){
for(int j = 0; j < n; j++){
cin >> a[i][j];
dp[i][j] = -1;
}
}
cout << dfs(n-1, n-1) << endl;
}
return 0;
}
Example:
Input:
2
5
31 100 65 12 18 10 13 47 157 6 100 113 174 11 33 88 124 41 20 140 99 32 111 41 20
2
42 93 7 14
Output:
327
63
I am getting 2147483647 as the output for both the cases, which is the value of INT_MAX.
The global variable n that dfs looks at is always zero (by static initialization), it's never assigned a value. When main calls, say, dfs(4, 4), the function immediately returns INT_MAX due to 4 >= 0 check.
Once you fix this simple issue, you'll discover that your program crashes due to stack overflow. You see, dfs(4, 4) calls dfs(3, 4), which in turn calls dfs(4, 4), which calls dfs(3, 4), which ...
This is not really a dynamic programming problem. It's a "shortest path in a graph" problem, suitable for, say, Dijkstra or A* algorithms.
I am trying to implement the Divide and Conquer Algorithm to solve the Traveling Salesman problem.
I divided the problem into smaller parts, but I have no idea what to do next.
Here is my code:
struct coordinate
{
float x;
float y;
};
vector<coordinate> coordinates; //Please assume it is filled with random coordinates
void DivideAndConquer(int divide)
{
vector<vector<coordinate>> routes;
vector<coordinate> empty;
int check = 0;
for (int i = 0; i < coordinates.size(); i++)
{
if (i == divide * check)
{
check++;
routes.push_back(empty);
}
routes[check - 1].push_back(coordinates[i]);
}
//What now?
}
I also implemented methods to calculate distance:
float Distance(coordinate first, coordinate second)
{
return sqrt(pow(second.x - first.x, 2) + pow(second.y - first.y, 2) * 1.0);
}
float RouteDistance(vector<coordinate> route, bool returnBack)
{
float totalDistance = 0;
for (int i = 1; i < route.size(); i++)
{
totalDistance += Distance(route[i-1], route[i]);
}
if (returnBack) totalDistance += Distance(route[0], route[route.size() - 1]);
return totalDistance;
}
I wrote Brute Force algorithm as well, which I believe can be used in divide and conquer.
It simply returns to most optimal route of given coordinate vector.
vector<coordinate> BruteForce(vector<coordinate> route)
{
vector<int> turn;
for (int i = 0; i < route.size(); i++) turn.push_back(i);
int currentBestDistance = RouteDistance(route, true);
vector<coordinate> currentBestRoute = route;
do
{
vector<coordinate> newRoute;
int newRouteDistance;
for (int e : turn)
{
newRoute.push_back(route[e]);
}
newRouteDistance = RouteDistance(newRoute, false);
if (newRouteDistance < currentBestDistance)
{
currentBestRoute = newRoute;
currentBestDistance = newRouteDistance;
}
} while (next_permutation(turn.begin(), turn.end()));
return currentBestRoute;
}
In DivideAndConquer it currently divides the coordinates vector into sub vectors size of the "divide" parameter we call the function with.
For example, let's assume this is our coordinates:
10 20
23 54
98 123
55 72
16 82
And we call "DivideAndConquer(2)"
result:
10 20
23 54
98 123
55 72
16 82
I have a string of numbers for example 469111252 and I know how to split from left-hand side but how to use substr to split it from right-hand side?
If digitsPerNode = 2
from left 46 91 11 25 2
But I want to get from right 52 12 11 69 4
//left hand side parse
for (int i=0;i<num.length(); i+=digitsPerNode) {
splitNum = num.substr(i,digitsPerNode);
}
Count from top to bottom not from bottom to top.
int numlength=num.length();
if(numlength%2==1)
numlength+=1;
for(int i=numlength;i>=0;i-=digitsPerNode)
{
splitNum = num.substr(i,digitsPerNode);
{
string a = "1234567890-=4";
for (int i = a.length() - 2; i >= -1; i = i - 2)
{
if (i < 0) cout << a.substr(i+1, 1) << endl;
else cout << a.substr(i, 2) << endl;
}
I found the solution with reverse function
DoublyLinkedList::DoublyLinkedList(string value, string dPerNode)
{
digitsPerNode = stoi(dPerNode);
string subString;
reverse(value.begin(), value.end());
for (int i = 0; i <= value.length(); i += digitsPerNode)
{
//cut string by digitsPerNode Ex: 3 500 123 412
subString = value.substr(i, digitsPerNode);
reverse(subString.begin(), subString.end());
insertAtHead(subString);
}
}
I have 2 vectors, one (vector1 of structs (Point)) is filled with X amount of points and another (vector2 of structs (PrimeTemplate)) is filled with Y amount of points. I want to find all values below a threshold and I feel like my code just doesn't do that. For now I'll just ignore if one point maps to more than 1 other. What am I missing? I only generate a few points and I know I should be getting more.
struct Template{
int tempX;
int tempY;
};
struct PrimeTemplate{
double tempX;
double tempY;
};
int matches = 0;
for (int outerLoop = 0; outerLoop < vector1 .size(); outerLoop++)
{
for (int innerLoop = 0; innerLoop < vector2.size(); innerLoop++)
{
double tempEuclidianX = std::pow(abs(vector1 [outerLoop].tempX - vector2[innerLoop].tempX), 2.0);
double tempEuclidianY = std::pow(abs(vector1 [outerLoop].tempY - vector2[innerLoop].tempY), 2.0);
double Euclidian = sqrt(tempEuclidianX + tempEuclidianY);
if (Euclidian <= 5) //less than threshold
{
matches++;
}
}
}
Sample input from a file would look like this (two different files, random numbers) (no worries about getting data, it's all there)
245 21
452 54
124 68
485 78
111 29
97 75
78 113
300 124
411 101
What is wrong with your code is that you use abs() before squaring.
It isn't necessary to take the absolute value at all before squaring, of course, but if you are going to then you want to use fabs, as just abs takes and returns an integer. This extra rounding off might be why are not getting the right answer.
This was the method I used for calculating the shortest distances between a pair. It loops through a text file and loads up the vectors you see. Turned out the issue with the points was in my implementation before this code which was some the normalization of Biometric points.
for (int outerLoop = 0; outerLoop < Tvector.size(); outerLoop++)
{
for (int innerLoop = 0; innerLoop < QPrimeVector.size(); innerLoop++)
{
double tempEuclidianX = std::pow((QPrimeVector[innerLoop].tempX - Tvector[outerLoop].tempX), 2.0);
double tempEuclidianY = std::pow((QPrimeVector[innerLoop].tempY - Tvector[outerLoop].tempY), 2.0);
double Euclidian = sqrt(tempEuclidianX + tempEuclidianY);
if (Euclidian <= THRESHOLD) //less than threshold and not taken already
{
if (Euclidian < minEuclidian)
{
minEuclidian = Euclidian;
if (!Tvector[outerLoop].marked)
{
matched = innerLoop;
}
}
}
if (matched != -1)
{
matches++;
}
matched = -1;
minEuclidian = 10;
}
if (matches > masterMatchCount)
{
masterMatchCount = matches;
deltaThetaMaster = deltaTheta;
deltaXMaster = deltaX;
deltaYMaster = deltaY;
}
}
for (int reset = 0; reset < Tvector.size(); reset++)
{
Tvector[reset].marked = false; //reset all the matches
}
QPrimeVector.clear();
}
I am reading some coordinates from a file and trying to assign them cell values (0-2) by diving them into a 3x3 grid. For some values the code is assigning negative cell values like for x=268 or x=269. Where am I going wrong?
I have file output.txt as follows with :
76 62
77 62
78 62
79 62
81 62
83 62
86 62
etc
The code to assign cells:
int x_points[99];
int y_points[99];
int i=0;
int x,y;
int max_x, max_y;
int min_x, min_y;
while(out.good())
{
out>>x;
out>>y;
if(i==0)
{
max_x=x;
min_x=x;
min_y=y;
max_y=y;
}
else if (x>max_x)
{
max_x=x;
}
else
if(x < min_x)
{
min_x=x;
}
else if (y>max_y)
{
max_y=y;
}
else
if(y < min_y)
{
min_y=y;
}
x_points[i]=x;
y_points[i]=y;
i++;
}
for(i=0; i<99; i++)
cout<<x_points[i]<<","<<y_points[i]<<"\n";
int cells_x[99];
int cells_y[99];
float x_width;
float y_width;
int divide = 3;
//To find out the cells. Divide it by 20
x_width=(max_x-min_x)/divide;
y_width=(max_y-min_y)/divide;
cout<<"\nx_width:"<<x_width;
cout<<"y_width:"<<y_width<<"\n";
int x1;
int y1;
for(i=0; i<99; i++)
{
x1=x_points[i]-min_x;
y1=y_points[i]-min_y;
for(int j=0; j<divide; j++)
{
if(j*x_width<=x1 && x1<((j+1)*x_width))
cells_x[i]=j;
if(j*y_width<=y1 && y1<((j+1)*y_width))
cells_y[i]=j;
}
cout<<cells_x[i]<<" "<<i<<" "<<cells_y[i]<<"\n";
}
The first problem I see is where you try to find the maximum and minimum values of x and y:
if(i==0)
{
max_x=x;
min_x=x;
min_y=y;
max_y=y;
}
else if (x>max_x)
{
max_x=x;
}
else if(x < min_x)
{
min_x=x;
}
else if (y>max_y) /* <-- This should not have an else! */
{
max_y=y;
}
else if(y < min_y)
{
min_y=y;
}
As written, it prevents the analysis of y values when an x is a new max or min. This will cause issues with the rest of your program, since max_y and min_y don't actually contain the max and min.
Next up is calculating the x_width and y_width:
x_width=(max_x-min_x)/divide; // should be x_width=(max_x-min_x + 1)/divide;
y_width=(max_y-min_y)/divide; // y_width=(max_y-min_y + 1)/divide;
If max_x = 8, and min_x = 0, your code would result in x_width = 8/3, or about 2.6666666666666666666666666666667. But 0-8 can be split up into 3 groups of 3. Adding 1 corrects this by calculating the number of points, not the length of the line.
It also prevents you from having a width of 0, which would happen if max_x == min_x. A width of 0 causes trouble in the next section:
for(int j=0; j<divide; j++)
{
/* an x_width of 0 will cause this to never evaluate to true */
/* x1 cannot ever be >= to 0 AND < 0 */
if(j*x_width<=x1 && x1<((j+1)*x_width))
cells_x[i]=j;
if(j*y_width<=y1 && y1<((j+1)*y_width))
cells_y[i]=j;
}
if x_width is zero, then you will never assign a value to cells_x[i], meaning it will still be set to its initialization value, which could be a negative number.