printing the closest pair of points - c++

I was writing this code to find the minimum distance between 2 points.The code I have written gives me the minimum distance correctly but does not give the correct coordinates from which the minimum distance is computed.Kindly help me identify the problem according to me this is the correct approach to print the points as well along with the minimum distance.
#include<bits/stdc++.h>
#define FOR(i,N) for(int i=0;i<(N);i++)
#define rep(i,a,n) for(int i=(a);i<(n);i++)
using namespace std;
struct point {
int x;
int y;
};
typedef struct point point;
void printarr(point arr[], int n) {for(int i = 0; i < n; i++) cout <<
arr[i].x << " " << arr[i].y << endl; cout << endl;
bool comparex(const point& X, const point& Y) { return X.x < Y.x; }
bool comparey(const point& X, const point& Y) { return X.y < Y.y; }
float getdis(point X, point Y) { return sqrt((X.x - Y.x)*(X.x - Y.x) + (X.y
- Y.y)*(X.y - Y.y)); }
float brutedis(point P[], int n, point A[]) {
float d = INT_MAX;
float temp;
FOR(i, n) {
rep(j, i+1, n) {
temp = getdis(P[i],P[j]);
if(temp < d) {
d = temp;
A[0].x = P[i].x; A[0].y = P[i].y;
A[1].x = P[j].x ; A[1].y = P[j].y;
}
}
}
return d;
}
float stripdis(point P[], int n, float d, point A[]) {
float temp = d;
float dis;
sort(P, P + n, comparey);
FOR(i, n) {
rep(j,i+1,n) {
if(abs(P[j].y - P[i].y) < d) {
dis = getdis(P[j], P[i]);
if(dis < temp) {
temp = dis;
A[0].x = P[i].x; A[0].y = P[i].y;
A[1].x = P[j].x ; A[1].y = P[j].y;
}
}
}
}
return temp;
}
float solve(point P[], int n, point A[]) {
if(n <= 3) return brutedis(P, n, A);
int mid = n/2;
point M = P[mid];
float d = min(solve(P, mid, A), solve(P+mid, n-mid, A));
point strip[n];
int j = 0;
int i = 0;
while(i < n) {
if(abs(P[i].x - M.x) < d) strip[j++] = P[i];
i++;
}
return min(d, stripdis(strip, j, d, A));
}
int main() {
point P[] = {{0, 0}, {-4,1}, {-7, -2}, {4, 5}, {1, 1}};
int n = sizeof(P) / sizeof(P[0]);
sort(P, P+n, comparex);
point A[2];
cout << "Minimum Distance = " << solve(P, n, A) << "\n";
printarr(A, 2);
//printarr(P, n);
return 0;
}

To the extent I can follow your badly formatted code, brutedis unconditionally modifies A[] and it gets called again after you have found the right answer (but don't know you found the right answer).
So if the first call were best in min(solve(P, mid, A), solve(P+mid, n-mid, A)); the second could still call brutedis and destroy A[]

You call solve twice, both giving it A as the parameter. Each of these calls always overwrite A, but only one returns the correct answer. And they both call brutedis that also always overwrites A.
The easiest way to fix this is to introduce an additional parameter to all these functions, that would contain the minimal distance found so far, the same way you did with stripdis.
float solve(point P[], int n, float d, point A[]) {
if(n <= 3) return brutedis(P, n, d, A);
...
d = solve(P, mid, d, A);
d = solve(P+mid, n-mid, d, A);
d = stripdis(strip, j, d, A));
...
float brutedis(point P[], int n, float d, point A[])
{
// float d = INT_MAX -- Not needed
Thus A will only be overeritten if the distance between the new pair of points is globally minimal so far.
No need to call min as each function already keeps the minimum of d and the distance it finds.

That is because after getting the correct coordinates in "A" array, you are again updating that. just look for the below statement in your code:
float d = min(solve(P, mid, A), solve(P+mid, n-mid, A));
this will give correct minimum distance but not correct coordinates. Just think about it, if your first call to solve, in the above statement has the minimum distance coordinates, then your second call is going to modify the coordinates in A[]. take a pen and paper and try to solve for the coordinates you have, it'll give you better understanding.

Related

How can I make this inverse modulo program take in larger numbers?

Heres the code:
int gcdExtended(int a, int b, int* x, int* y);
void modInverse(int A, int M)
{
int x, y;
int g = gcdExtended(A, M, &x, &y);
if (g != 1)
cout << "Inverse doesn't exist";
else {
int res = (x % M + M) % M;
cout << "Modular multiplicative inverse is " << res;
}
}
int gcdExtended(int a, int b, int* x, int* y)
{
// Base Case
if (a == 0) {
*x = 0, *y = 1;
return b;
}
// To store results of recursive call
int x1, y1;
int gcd = gcdExtended(b % a, a, &x1, &y1);
*x = y1 - (b / a) * x1;
*y = x1;
return gcd;
}
I'm not sure how to take in bigger numbers like 15001 (mod 5729413260) without getting overflow. Should I not use recursion? I tried long long but that didn't work, any suggestions?
You might change int to long long; if that's not sufficient, then boost::multiprecision might help.

Dynamic programming - Gold mine grid optimization TLE

I'm trying to solve Gold Mine problem from https://practice.geeksforgeeks.org/problems/gold-mine-problem2608/1/#. I am receiving TLE for the following code. I have looked at the solution also yet dont understand what minor mistake I made that the code received TLE and the solution code.
class Solution{
public:
int helper(int a , int b, int n , int m , vector<vector<int>> M, vector<vector<int>> &N){
if(a<0 || b<0 || a>=n){
return INT_MIN ;
}
if(N[a][b]!=-1){
return N[a][b];
}
if(b==m){
N[a][b] = 0;
return 0;
}
else{
N[a][b] = M[a][b] + max( (helper(a+1,b+1,n,m,M,N)) , max(helper(a-1,b+1,n,m,M,N),helper(a,b+1,n,m,M,N)));
return N[a][b] ;
}
// return N[a][b];
}
int maxGold(int n, int m, vector<vector<int>> M)
{
// code here
vector<vector<int>> N(n,vector<int>(m+1,-1) );
int ans = 0 ;
for(int i=0; i<n; i++){
// int ans2 = helper(i,0,n,m,M,N);
// if(ans2>ans){
// ans = ans2;
// }
ans = max(ans,helper(i,0,n,m,M,N));
}
return ans;
// just one extra in right to store 0s
// position a,b to a,b
// n,m to n-1,m-1
}
};
The solution given on the site :
// C++ program to solve Gold Mine problem
#include<bits/stdc++.h>
using namespace std;
int collectGold(vector<vector<int>> gold, int x, int y, int n, int m, vector<vector<int>> &dp) {
// Base condition.
if ((x < 0) || (x == n) || (y == m)) {
return 0;
}
if(dp[x][y] != -1){
return dp[x][y] ;
}
// Right upper diagonal
int rightUpperDiagonal = collectGold(gold, x - 1, y + 1, n, m, dp);
// right
int right = collectGold(gold, x, y + 1, n, m, dp);
// Lower right diagonal
int rightLowerDiagonal = collectGold(gold, x + 1, y + 1, n, m, dp);
// Return the maximum and store the value
return dp[x][y] = gold[x][y] + max(max(rightUpperDiagonal, rightLowerDiagonal), right);
}
int getMaxGold(vector<vector<int>> gold, int n, int m)
{
int maxGold = 0;
// Initialize the dp vector
vector<vector<int>> dp(n, vector<int>(m, -1)) ;
for (int i = 0; i < n; i++) {
// Recursive function call for ith row.
int goldCollected = collectGold(gold, i, 0, n, m, dp);
maxGold = max(maxGold, goldCollected);
}
return maxGold;
}
I suppose that calculating all 3 directions differently and then taking max seems to make the actual solution faster, but would like to understand the reason for the same to improve myself.
EDIT1 - Nope, still received TLE after calculating differently for all 3 directions, although it did manage to do more test cases which I dont understand why.

Average of three biggest parameters out of five without using sorting algorithm or vector/array

I'm trying to create a function with has 5 input parameters and returns the average of the 3 biggest. However I'm not supposed to use a sorting algorithm, vector/arrays or function libraries and still try to use to develop the most efficient logic possible.
So far I've come up with the code below. Is it the most efficient possible considering the restrictions?
float avg3of5(float a, float b, float c, float d, float e) {
float min;
float min2;
min = a;
if (b < min) {
min2 = min;
min = b;
}
else {
min2 = b;
}
if (c < min) {
min2 = min;
min = c;
}
else {
if (c < min2) {
min2 = c;
}
}
if (d < min) {
min2 = min;
min = d;
}
else {
if (d < min2) {
min2 = d;
}
}
if (e < min) {
min2 = min;
min = e;
}
else {
if (e < min2) {
min2 = e;
}
}
Return = (a + b + c + d + e - min - min2) / 3
}
One thing that immediately jumps out at me is the repetition caused by:
if (b < min) {
min2 = min;
min = b;
}
else {
min2 = b;
}
It may be better to extract this logic into a function and then call it instead:
#include <iostream>
float avg3of5(const float, const float, const float, const float, const float);
void adjustmins(const float, float*, float*);
int main()
{
std::cout << avg3of5(4,6,2,6,3);
}
float avg3of5(const float a, const float b, const float c, const float d, const float e){
float min;
float min2;
min = a;
adjustmins(b, &min, &min2);
adjustmins(c, &min, &min2);
adjustmins(d, &min, &min2);
adjustmins(e, &min, &min2);
return (a + b + c + d + e - min - min2) / 3;
}
void adjustmins(const float n, float* min, float* min2){
if (n < *min) {
*min2 = *min;
*min = n;
}
else {
*min2 = n;
}
}
I can't tell you if this is more efficient in terms of processing time, but there's much less repetition.
If you'd prefer to use references rather than pointers use this (C++ only):
void adjustmins(const float, float&, float&);
and
void adjustmins(const float n, float& min, float& min2){
if (n < min) {
min2 = min;
min = n;
}
else {
min2 = n;
}
}
then call with:
adjustmins(b, min, min2);

Expected Contant Expression [duplicate]

This question already has answers here:
How do I use arrays in C++?
(5 answers)
Why aren't variable-length arrays part of the C++ standard?
(10 answers)
Closed 8 years ago.
I was implementing a version of the closest pair problem using the algorithmic technique of divide and conquer. However, when I try and compile my code, in several spots I get the error "Expected constant expression". I am aware that arrays are supposed to have constant values in them, but I'm not quite sure what's wrong in this case. I tried to research solutions and many people suggested using malloc, but it seems to be generally frowned upon. Would someone be able to help me fix this? Below is the code with the errors commented hopefully well enough that you can see them. Thank you so much in advance for your help, I really appreciate it!
#include <iostream>
#include <float.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
//A struct to represent the points on an x,y plane
struct Point{
int x, y;
};
//function to sort x coordinates
int compareX(const void* a, const void* b){
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->x - p2->x);
}
//function to sort y coordinates
int compareY(const void* a, const void* b){
Point *p1 = (Point *)a, *p2 = (Point *)b;
return (p1->y - p2->y);
}
//function to find the distance between any two points
float dist(Point p1, Point p2){
return sqrt( (float)(p1.x - p2.x) * (p1.x - p2.x) +
(float)(p1.y - p2.y) * (p1.y - p2.y)
);
}
//utility function to find the minimum of any two float values
float min(float x, float y){
if(x < y)
return x;
else
return y;
}
//brute force function to find the closest of two points
float bruteforce(Point P[], int n){
float min = FLT_MAX;
for(int i=0; i<n; i++){
for(int j = i+1; j < n; j++)
if(dist(P[i], P[j]) < min)
min = dist(P[i], P[j]);
}
return min;
}
//function to find the distance between the closest points of a given size
float closestArray(Point array1[], int size, float d){
float min = d; //initialize the minimum distance as d
//go through the points 1 by 1 and try the next until the difference is smaller than d
for (int i=0; i < size; i++)
for (int j= i + 1; j< size && (array1[i].y - array1[i].y) < min; j++)
if(dist(array1[i],array1[j]) < min)
min = dist(array1[i], array1[j]);
return min;
}
float closestPoint(Point Px[], Point Py[], int n){
if(n <= 3)
return bruteforce(Px, n);
//find the middle point
int mid = n/2;
Point midPoint = Px[mid];
//divide the points along the vertical line
Point Pyleft[mid + 1]; //left of vertical line <--- ERROR
Point Pyright[n-mid-1]; //right of vertical line <--- ERROR
int li = 0; //index of left subarray
int ri = 0; //index of right subarray
for ( int i =0; i<n; i++){
if (Py[i].x <= midPoint.x)
Pyleft[li++] = Py[i];
else
Pyright[ri++] = Py[i];
}
//calculate the smallest ditance dl on the left middle point and dr on the right side
float dl = closestPoint(Px, Pyleft, mid);
float dr = closestPoint(Px + mid, Pyright, n-mid);
//find the smaller of the two distances
float d = min(dl, dr);
//build another array Q that contains points closer than d to the line passing through the middle
Point q[n]; // <--- ERROR
int j = 0;
for (int i = 0; i<n; i++)
if(abs(Py[i].x - midPoint.x) < d)
q[j] = Py[i], j++;
return min(d, closestArray(q, j, d) );
}
//function that finds the smallerst distance
float closest(Point P[], int n){
Point Px[n]; //<--- ERROR
Point Py[n]; //<---ERROR
for(int i=0; i < n; i++)
{
Px[i] = P[i];
Py[i] = P[i];
}
qsort(Px, n, sizeof(Point), compareX);
qsort(Py, n, sizeof(Point), compareY);
//recursive function to find smallest distance
return closestPoint(Px, Py, n);
}
int main()
{
Point P[] = {{2, 3}, {12, 30}, {40, 50}, {5, 1}, {12, 10}, {3, 4}};
int n = sizeof(P) / sizeof(P[0]);
cout << "The smallest distance is " << closest(P, n);
return 0;
}

Superellipse Stroustrup

Exercise 13, from Chapter 12 of Stroustrup's Programming principles and practice using c++.
A superellipse is a two-dimensional shape defined by the equation
Look up superellipse on the web to get a better idea of what such
shapes look like. Write a program that draws "starlike" patterns by
connecting points on a superellipse. Take a, b, m, n, and N as
arguments.
Select N points on the superellipse defined by a, b, m,
and n. Make the points equally spaced for some definition of
"equal" Connect each of those N points to one or more other points
(if you like you can make the number of points connected to another
argument or just use N-1, i.e., all me orner points).
i have a vector that contains points with which i can build the superellipse
i cant get the second part of exercise - how to find N-points lying on superellipse to build stars?
thanks
//------------------------------------------------------------------------------
struct Point {
int x, y;
Point(int xx, int yy) : x(xx), y(yy) { }
Point() :x(0), y(0) { }
};
//------------------------------------------------------------------------------
int sgn(double d) {
if (d < 0)
return -1;
if (d == 0)
return 0;
if (d > 0)
return 1;
// exception
error("sgn: something gone wrong\n");
}
//------------------------------------------------------------------------------
vector<Point> superellipse(double a, double b, double m, double n, double precision = 0.01, int xCenter = 200, int yCenter = 200) {
if (precision >= 1.00 || precision < 0.001)
error ("use numbers from range [0.001 ; 1.00) for precision parametr\n");
vector<Point> points;
Point temp;
Point P;
for (double d = -1.0; d < 1.00; d += precision) {
double t = d*M_PI;
int x = pow((abs(cos(t))),2.0/m) * a * sgn(cos(t));
int y = pow((abs(sin(t))),2.0/n) * b * sgn(sin(t));
P = Point(x + xCenter, y + yCenter);
if (P != temp) // ignore dublicates
points.push_back(P);
temp = P;
}
return points;
}
//------------------------------------------------------------------------------
1.scratch
vector<Point> superellipse (/*...*/) {
/* */
return points;
}
2.put
class Superellipse {
std::vector<Point> _points;
void draw_connected(const Point& A, const Point& B);
public:
void draw_star(/* params */);
Superellipse(/* params*/){
/* initialize _points*/
}
};
i cant get the second part of exercise - how to find N-points lying on
superellipse to build stars?
???
You already have the points in your vector.
http://www.stroustrup.com/Programming/programming_ch12.pdf
if you like you can make the number of points connect to another
argument or just use N–1, i.e., all the other points
void Superellipse::draw_star (/* */){
int N = _points.size();
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
draw_connected (_points[i], _points[j]);
}
}
}