Open In App

Finding Minimum Time for Workers to Meet at a Point

Last Updated : 28 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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;
 
// Method to calculate the minimum time needed for all
// workers to reach point X
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 };
    // Initialize the range of meeting point
    double lo = *min_element(point, point + N),
           hi = *max_element(point, point + N);
 
    // Reduce the range by 200 iterations
    ll cnt = 200;
 
    // Ternary Search
    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




// implementation of finding minimum time for workers to
// meet at a point in java
import java.io.*;
 
class GFG {
    // Method to calculate the minimum time needed for all
    // workers to reach point X
    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 };
        // Initialize the range of meeting point
        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]);
        }
 
        // Reduce the range by 200 iterations
        int cnt = 200;
 
        // Ternary Search
        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)));
    }
}
// This Code is Contributed by BUNNYBOY950


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]
 
    # Initialize the range of meeting point
    lo, hi = min(point), max(point)
 
    # Reduce the range by 200 iterations
    cnt = 200
 
    # Ternary Search
    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 {
    // Method to calculate the minimum time needed for all
    // workers to reach point X
    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 };
 
        // Initialize the range of the meeting point
        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]);
        }
 
        // Reduce the range by 200 iterations
        int cnt = 200;
 
        // Ternary Search
        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




// Method to calculate the minimum time needed for all
// workers to reach point X
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];
 
    // Initialize the range of meeting point
    let lo = Math.min(...point);
    let hi = Math.max(...point);
 
    // Reduce the range by 200 iterations
    let cnt = 200;
 
    // Ternary Search
    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();


Output

3.500000










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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads