Magnets are placed on X axis, the coordinates of which are given in sorted order, you need to find out the X-coordinates of all the equilibrium points (i.e. the point where net force is zero).
- The polarity of the magnet is such that exerts +ve force in its right side and -ve force in left side, (here +ve is considered in +ve direction of x-axis).
- Forces are inversely proportional to the distance, thus there lies an equilibrium point between every two magnetic points.
You are given a sorted integer array arr[], where arr[i] denotes the coordinate of the i-th point on the X-axis, you need to find all the points x on which the net force of all magnets (or the below expression) is 0.
It is guaranteed that there exists exactly one such point in every open interval (arr[i], arr[i + 1]) for 0 ≤ i < n - 1. Return an array containing all n - 1 points, each accurate to 2 decimal places.
Examples:
Input: arr[] = [1, 2]
Output: [1.50]
Explanation: The mid point of two points will have net force zero, thus answer = 1.50.Input: arr[] = [0, 10, 20, 30]
Output: [3.82, 15.00, 26.18]
Explanation:
1. Between 0 and 10: The points at 20 and 30 also contribute to the force, so the equilibrium point shifts toward 0, giving 3.82 instead of the midpoint (5).
2. Between 10 and 20: The arrangement is symmetric about 15, so the forces balance exactly at 15.00.
3. Between 20 and 30: By symmetry with the first interval, the equilibrium point is 26.18, shifted toward 30.
Using Binary Search - O(n ^ 2) Time and O(1) Space
For every pair of adjacent magnets, there is exactly one equilibrium point where the net force becomes zero. Since the net force varies monotonically within each interval, the idea is to efficiently locate this point using binary search.
We continue the binary search until the search interval becomes smaller than a predefined precision (1e-6). Since the interval shrinks by half in every iteration, once its length is less than 1e-6, the equilibrium point is accurate enough to satisfy the required output precision of 2 decimal places.
- For each pair of adjacent magnets, initialize the search interval as low = arr[i] and high = arr[i + 1].
- Perform binary search while the interval length (high - low) is greater than the predefined precision (1e-6).
- In each iteration, compute the midpoint and calculate the net force at that point.
- If the net force is positive, move low to mid; otherwise, move high to mid.
- Once the interval becomes smaller than 1e-6, store the midpoint (low + high) / 2 as the equilibrium point.
- Repeat the above process for all adjacent pairs and return the list of equilibrium points.
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the net force at point x
double evaluateFunction(double x, const vector<int> &arr)
{
// Variable to store the total force
double force = 0.0;
// Add the force contributed by every magnet
for (int pos : arr)
force += 1.0 / (x - pos);
// Return the net force at point x
return force;
}
// Function to find all equilibrium points
vector<double> nullPoints(vector<int> &arr)
{
int n = arr.size();
// Vector to store the equilibrium points
vector<double> ans;
// Desired precision for binary search
const double EPS = 1e-6;
// Find one equilibrium point between every pair of adjacent magnets
for (int i = 0; i < n - 1; i++)
{
// Search space lies between two consecutive magnets
double low = arr[i];
double high = arr[i + 1];
// Continue until the interval becomes sufficiently small
while (high - low > EPS)
{
// Find the middle point
double mid = low + (high - low) / 2.0;
// Compute the net force at the midpoint
double force = evaluateFunction(mid, arr);
// If the net force is positive, equilibrium lies on the right
if (force > 0)
low = mid;
// Otherwise, equilibrium lies on the left
else
high = mid;
}
// Store the equilibrium point
ans.push_back((low + high) / 2.0);
}
// Return all equilibrium points
return ans;
}
// Driver code
int main()
{
vector<int> arr = {1, 2, 3};
// Find all equilibrium points
vector<double> ans = nullPoints(arr);
// Print the answer up to 2 decimal places
cout << fixed << setprecision(2);
for (double x : ans)
cout << x << " ";
return 0;
}
import java.util.*;
class GFG {
// Function to calculate the net force at point x
static double evaluateFunction(double x,
List<Integer> arr)
{
// Variable to store the total force
double force = 0.0;
// Add the force contributed by every magnet
for (int pos : arr)
force += 1.0 / (x - pos);
// Return the net force at point x
return force;
}
// Function to find all equilibrium points
static List<Double> nullPoints(List<Integer> arr)
{
int n = arr.size();
// List to store the equilibrium points
List<Double> ans = new ArrayList<>();
// Desired precision for binary search
final double EPS = 1e-6;
// Find one equilibrium point between every pair of
// adjacent magnets
for (int i = 0; i < n - 1; i++) {
// Search space lies between two consecutive
// magnets
double low = arr.get(i);
double high = arr.get(i + 1);
// Continue until the interval becomes
// sufficiently small
while (high - low > EPS) {
// Find the middle point
double mid = low + (high - low) / 2.0;
// Compute the net force at the midpoint
double force = evaluateFunction(mid, arr);
// If the net force is positive, equilibrium
// lies on the right
if (force > 0)
low = mid;
// Otherwise, equilibrium lies on the left
else
high = mid;
}
// Store the equilibrium point
ans.add((low + high) / 2.0);
}
// Return all equilibrium points
return ans;
}
// Driver code
public static void main(String[] args)
{
List<Integer> arr = Arrays.asList(1, 2, 3);
// Find all equilibrium points
List<Double> ans = nullPoints(arr);
// Print the answer up to 2 decimal places
for (double x : ans)
System.out.printf("%.2f ", x);
}
}
# Function to calculate the net force at point x
def evaluateFunction(x, arr):
# Variable to store the total force
force = 0.0
# Add the force contributed by every magnet
for pos in arr:
force += 1.0 / (x - pos)
# Return the net force at point x
return force
# Function to find all equilibrium points
def nullPoints(arr):
n = len(arr)
# List to store the equilibrium points
ans = []
# Desired precision for binary search
EPS = 1e-6
# Find one equilibrium point between every pair of adjacent magnets
for i in range(n - 1):
# Search space lies between two consecutive magnets
low = arr[i]
high = arr[i + 1]
# Continue until the interval becomes sufficiently small
while high - low > EPS:
# Find the middle point
mid = low + (high - low) / 2.0
# Compute the net force at the midpoint
force = evaluateFunction(mid, arr)
# If the net force is positive, equilibrium lies on the right
if force > 0:
low = mid
# Otherwise, equilibrium lies on the left
else:
high = mid
# Store the equilibrium point
ans.append((low + high) / 2.0)
# Return all equilibrium points
return ans
# Driver code
if __name__ == "__main__":
arr = [1, 2, 3]
# Find all equilibrium points
ans = nullPoints(arr)
# Print the answer up to 2 decimal places
for x in ans:
print(f"{x:.2f}", end=" ")
using System;
using System.Collections.Generic;
class GFG {
// Function to calculate the net force at point x
static double EvaluateFunction(double x, List<int> arr)
{
// Variable to store the total force
double force = 0.0;
// Add the force contributed by every magnet
foreach(int pos in arr) force += 1.0 / (x - pos);
// Return the net force at point x
return force;
}
// Function to find all equilibrium points
static List<double> nullPoints(List<int> arr)
{
int n = arr.Count;
// List to store the equilibrium points
List<double> ans = new List<double>();
// Desired precision for binary search
const double EPS = 1e-6;
// Find one equilibrium point between every pair of
// adjacent magnets
for (int i = 0; i < n - 1; i++) {
// Search space lies between two consecutive
// magnets
double low = arr[i];
double high = arr[i + 1];
// Continue until the interval becomes
// sufficiently small
while (high - low > EPS) {
// Find the middle point
double mid = low + (high - low) / 2.0;
// Compute the net force at the midpoint
double force = EvaluateFunction(mid, arr);
// If the net force is positive, equilibrium
// lies on the right
if (force > 0)
low = mid;
// Otherwise, equilibrium lies on the left
else
high = mid;
}
// Store the equilibrium point
ans.Add((low + high) / 2.0);
}
// Return all equilibrium points
return ans;
}
// Driver code
static void Main()
{
List<int> arr = new List<int>{ 1, 2, 3 };
// Find all equilibrium points
List<double> ans = nullPoints(arr);
// Print the answer up to 2 decimal places
foreach(double x in ans) Console.Write($"{x:F2} ");
}
}
// Function to calculate the net force at point x
function evaluateFunction(x, arr)
{
// Variable to store the total force
let force = 0.0;
// Add the force contributed by every magnet
for (let pos of arr)
force += 1.0 / (x - pos);
// Return the net force at point x
return force;
}
// Function to find all equilibrium points
function nullPoints(arr)
{
const n = arr.length;
// Array to store the equilibrium points
const ans = [];
// Desired precision for binary search
const EPS = 1e-6;
// Find one equilibrium point between every pair of
// adjacent magnets
for (let i = 0; i < n - 1; i++) {
// Search space lies between two consecutive magnets
let low = arr[i];
let high = arr[i + 1];
// Continue until the interval becomes sufficiently
// small
while (high - low > EPS) {
// Find the middle point
const mid = low + (high - low) / 2.0;
// Compute the net force at the midpoint
const force = evaluateFunction(mid, arr);
// If the net force is positive, equilibrium
// lies on the right
if (force > 0)
low = mid;
// Otherwise, equilibrium lies on the left
else
high = mid;
}
// Store the equilibrium point
ans.push((low + high) / 2.0);
}
// Return all equilibrium points
return ans;
}
// Driver code
const arr = [ 1, 2, 3 ];
// Find all equilibrium points
const ans = nullPoints(arr);
// Variable to store the output
let output = "";
// Append each equilibrium point to the output string
for (const x of ans)
output += x.toFixed(2) + " ";
// Print the final output
console.log(output.trim());
Output
1.42 2.58