Finding Minimum Time for Workers to Meet at a Point
Last Updated :
28 Dec, 2023
Given N workers standing on a road of infinite length and two arrays point[] and time[] each of size N, such that point[i] is point where the ith worker is standing and time[i] is time needed for the ith worker to finish his task, find the minimum time when all the workers can finish their tasks and meet at a point. Consider that all the workers move with the same speed (1 unit distance per unit time). The worker has to finish the task before starting to move.
Note: The answer should be correct up to 6 decimal places.
Examples:
Input: N = 3, point = [1, 2, 3], time = [0, 0, 0]
Output: 1
Explanation: The first worker moves to position 2 in 1 unit of time, the second worker doesn’t need to move and the third worker moves to position 2 in 1 unit of time.
Input: N = 3, point = [1, 2, 3], time = [2, 2, 3]
Output: 3.5
Explanation: After 3.5 units of time, all the workers can meet at position 2.5
Approach:
Suppose that the point where the all the workers can meet in minimum time be X, then as we move away from point X in left or right direction the time to meet will keep on increasing. This is same as Unimodal function, so we can use Ternary Search to find the meeting point and then calculate the time for all the workers to reach the meeting point. We will initialize lo as the smallest point and hi as the largest point because the meeting point cannot lie outside this. Then, we can find 2 mid points mid1 and mid2. Calculate the time for all workers to reach mid1 as val1 and time for all workers to reach mid2 as val2. Now according to the values of val1 and val2, we can have one of the three cases:
- If val1 == val2, we can shift lo to mid1 and hi to mid2
- Else if val1 < val2, we can shift hi to mid2
- Else if val1 > val2, we can shift lo to mid1
Since the error limit is 1e-6 and in each iteration we are reducing our search space by a factor of at least 2/3. Therefore, 200 iterations are sufficient to get the meeting point. Calculate and return the time for all workers to reach the lo or hi.
Step-by-step approach:
- Initialize lo = smallest value in point[] and hi = largest value in point[]
- Find 2 mid points (mid1 and mid2) between lo and hi.
- Store the time needed for all workers to reach mid1 as val1.
- Store the time needed for all workers to reach mid2 as val2.
- Reduce the search space according to the values of val1 and val2.
- After 200 iterations, return the answer as the time needed for all workers to reach lo or hi.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define ll long long
using namespace std;
double solve(ll* point, ll* time , ll N, double X)
{
double maxTime = 0;
for ( int i = 0; i < N; i++) {
maxTime = max(maxTime, abs (point[i] - X) + time [i]);
}
return maxTime;
}
int main()
{
ll N = 3;
ll point[] = { 1, 2, 3 };
ll time [] = { 2, 2, 3 };
double lo = *min_element(point, point + N),
hi = *max_element(point, point + N);
ll cnt = 200;
while (cnt--) {
double mid1 = lo + (hi - lo) / 3.0;
double mid2 = hi - (hi - lo) / 3.0;
double val1 = solve(point, time , N, mid1);
double val2 = solve(point, time , N, mid2);
if (val1 == val2) {
lo = mid1;
hi = mid2;
}
else if (val1 < val2) {
hi = mid2;
}
else {
lo = mid1;
}
}
cout << fixed << setprecision(6)
<< solve(point, time , N, lo) << "\n";
}
|
Java
import java.io.*;
class GFG {
public static double solve( int [] point, int [] time,
int N, double X)
{
double maxTime = 0 ;
for ( int i = 0 ; i < N; i++) {
maxTime = Math.max(
maxTime, Math.abs(point[i] - X) + time[i]);
}
return maxTime;
}
public static void main(String[] args)
{
int N = 3 ;
int point[] = { 1 , 2 , 3 };
int time[] = { 2 , 2 , 3 };
double lo = Double.MAX_VALUE;
double hi = - 1 ;
for ( int i = 0 ; i < N; i++) {
lo = Math.min(lo, point[i]);
hi = Math.max(hi, point[i]);
}
int cnt = 200 ;
while (cnt != 0 ) {
double mid1 = lo + (hi - lo) / 3.0 ;
double mid2 = hi - (hi - lo) / 3.0 ;
double val1 = solve(point, time, N, mid1);
double val2 = solve(point, time, N, mid2);
if (val1 == val2) {
lo = mid1;
hi = mid2;
}
else if (val1 < val2) {
hi = mid2;
}
else {
lo = mid1;
}
cnt--;
}
System.out.print(String.format(
"%.6f" , solve(point, time, N, lo)));
}
}
|
Python3
import sys
def solve(point, time, N, X):
max_time = 0
for i in range (N):
max_time = max (max_time, abs (point[i] - X) + time[i])
return max_time
def main():
N = 3
point = [ 1 , 2 , 3 ]
time = [ 2 , 2 , 3 ]
lo, hi = min (point), max (point)
cnt = 200
while cnt > 0 :
mid1 = lo + (hi - lo) / 3.0
mid2 = hi - (hi - lo) / 3.0
val1 = solve(point, time, N, mid1)
val2 = solve(point, time, N, mid2)
if val1 = = val2:
lo = mid1
hi = mid2
elif val1 < val2:
hi = mid2
else :
lo = mid1
cnt - = 1
print ( "{:.6f}" . format (solve(point, time, N, lo)))
if __name__ = = "__main__" :
sys.exit(main())
|
C#
using System;
class GFG {
public static double Solve( int [] point, int [] time,
int N, double X)
{
double maxTime = 0;
for ( int i = 0; i < N; i++) {
maxTime = Math.Max(
maxTime, Math.Abs(point[i] - X) + time[i]);
}
return maxTime;
}
public static void Main( string [] args)
{
int N = 3;
int [] point = { 1, 2, 3 };
int [] time = { 2, 2, 3 };
double lo = double .MaxValue;
double hi = -1;
for ( int i = 0; i < N; i++) {
lo = Math.Min(lo, point[i]);
hi = Math.Max(hi, point[i]);
}
int cnt = 200;
while (cnt != 0) {
double mid1 = lo + (hi - lo) / 3.0;
double mid2 = hi - (hi - lo) / 3.0;
double val1 = Solve(point, time, N, mid1);
double val2 = Solve(point, time, N, mid2);
if (val1 == val2) {
lo = mid1;
hi = mid2;
}
else if (val1 < val2) {
hi = mid2;
}
else {
lo = mid1;
}
cnt--;
}
Console.Write(String.Format(
"{0:F6}" , Solve(point, time, N, lo)));
}
}
|
Javascript
function solve(point, time, X) {
let maxTime = 0;
for (let i = 0; i < point.length; i++) {
maxTime = Math.max(maxTime, Math.abs(point[i] - X) + time[i]);
}
return maxTime;
}
function main() {
const N = 3;
const point = [1, 2, 3];
const time = [2, 2, 3];
let lo = Math.min(...point);
let hi = Math.max(...point);
let cnt = 200;
while (cnt--) {
let mid1 = lo + (hi - lo) / 3.0;
let mid2 = hi - (hi - lo) / 3.0;
let val1 = solve(point, time, mid1);
let val2 = solve(point, time, mid2);
if (val1 === val2) {
lo = mid1;
hi = mid2;
} else if (val1 < val2) {
hi = mid2;
} else {
lo = mid1;
}
}
console.log(solve(point, time, lo).toFixed(6));
}
main();
|
Time Complexity: O(N * log3( max(point) )), where N is the number of workers and max(point) is the maximum value in point[] array
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...