Minimum time required by n cars to travel through all of the m roads
Given m roads and n cars. The cars are numbered from 1 to n. You are also given an array arr[] of size m, each road has a value arr[i] – the index of a car that runs fast on this road. If a car is fast on a road, then it travels across the road in 1 hour, else it takes 2 hours (if not proficient) to travel through this road. Find out the minimum time required by these n cars to travel through all of these m roads.
All cars run independently of each other and each car can run on a single road at once. All roads have the same length.
Examples:
Input: N = 2, M = 4, arr[] = {1, 2, 1, 2}
Output: 2
Explanation: The first car will run on the 1st and 3rd roads and the Second car will be running on the 2nd and 4th roads. Both cars completed 2 roads in 2 hours as both are proficient in traveling their corresponding roads.
Input: N = 2, M = 4, arr[] = {1, 1, 1, 1}
Output: 3
Explanation: The first car will run on the 1st, 2nd, and 3rd roads, whereas the 4th road will be assigned to the 2nd car. The first car will be finishing his road in 3 hours, whereas the second car spends 2 hours (as the 2nd car is not proficient in traveling the 4th road).
Approach: The problem can be solved based on the following observation.
If you can use the cars in such a way that all roads can be traveled in time x, Then, you can complete all these roads using x + 1 or more time as well.
Follow the steps mentioned below to implement the idea:
- As we are binary searching for the answer, we have to define the upper bound.
- In the Worst case, the total time can be 2 * m hours to travel through all roads. For example: if you assign all roads to a single car, and this car is not proficient in any of these roads.
- To check whether all roads can be completed in the given time we will be creating a lambda function.
- The function will be keeping track of free roads and needed roads.
- If the given time is greater than the total roads assigned to a car.
- Add the extra time to the free roads slot.
- Else, Add the left roads to the needed road.
- In the end, if needed roads are greater than the free roads slot, Thus it is not possible to complete all of the roads in the given time amount.
Below is the Implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void minTimeRequired( int n, int m, vector< int > arr)
{
vector< int > cnt(n + 1);
for ( int i = 0; i < m; i++)
cnt[arr[i]]++;
auto check = [&]( int time ) {
long long free = 0, needed = 0;
for ( int i = 1; i <= n; i++) {
if ( time >= cnt[i]) {
long long extraTime = ( time - cnt[i]);
free += extraTime / 2;
}
else {
needed += cnt[i] - time ;
}
}
return needed <= free ;
};
int l = 0, r = 2 * m;
int minTime = -1;
while (l <= r) {
int m = (l + r) / 2;
if (check(m)) {
minTime = m;
r = m - 1;
}
else {
l = m + 1;
}
}
cout << minTime << '\n' ;
}
int main()
{
int n = 2, m = 4;
vector< int > arr(m);
arr = { 1, 2, 1, 2 };
minTimeRequired(n, m, arr);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.util.function.Function;
class GFG {
static void minTimeRequired( int n, int m, int [] arr)
{
int [] cnt = new int [n + 1 ];
for ( int i = 0 ; i < m; i++) {
cnt[arr[i]]++;
}
Function<Integer, Boolean> check = (time) ->
{
long free = 0 , needed = 0 ;
for ( int i = 1 ; i <= n; i++) {
if (time >= cnt[i]) {
long extraTime = (time - cnt[i]);
free += extraTime / 2 ;
}
else {
needed += cnt[i] - time;
}
}
return needed <= free;
};
int l = 0 , r = 2 * m;
int minTime = - 1 ;
while (l <= r) {
int mid = (l + r) / 2 ;
if (check.apply(mid)) {
minTime = mid;
r = mid - 1 ;
}
else {
l = mid + 1 ;
}
}
System.out.println(minTime);
}
public static void main(String[] args)
{
int n = 2 , m = 4 ;
int [] arr = { 1 , 2 , 1 , 2 };
minTimeRequired(n, m, arr);
}
}
|
Python3
def minTimeRequired(n, m, arr):
cnt = [ 0 for _ in range (n + 1 )]
for i in range ( 0 , m):
cnt[arr[i]] + = 1
def check(time):
free = 0
needed = 0
for i in range ( 1 , n + 1 ):
if (time > = cnt[i]):
extraTime = (time - cnt[i])
free + = extraTime / / 2
else :
needed + = cnt[i] - time
return needed < = free
l = 0
r = 2 * m
minTime = - 1
while (l < = r):
m = (l + r) / / 2
if (check(m)):
minTime = m
r = m - 1
else :
l = m + 1
print (minTime)
if __name__ = = "__main__" :
n = 2
m = 4
arr = [ 0 for _ in range (m)]
arr = [ 1 , 2 , 1 , 2 ]
minTimeRequired(n, m, arr)
|
C#
using System;
using System.Linq;
class Program
{
static void Main( string [] args)
{
int n = 2, m = 4;
int [] arr = { 1, 2, 1, 2 };
MinTimeRequired(n, m, arr);
}
static void MinTimeRequired( int n, int m, int [] arr)
{
int [] cnt = new int [n + 1];
for ( int i = 0; i < m; i++)
{
cnt[arr[i]]++;
}
Func< int , bool > check = (time) =>
{
long free = 0, needed = 0;
for ( int i = 1; i <= n; i++)
{
if (time >= cnt[i])
{
long extraTime = (time - cnt[i]);
free += extraTime / 2;
}
else
{
needed += cnt[i] - time;
}
}
return needed <= free;
};
int l = 0, r = 2 * m;
int minTime = -1;
while (l <= r)
{
int mid = (l + r) / 2;
if (check(mid))
{
minTime = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
Console.WriteLine(minTime);
}
}
|
Javascript
function minTimeRequired(n, m, arr) {
let cnt = new Array(n + 1).fill(0);
for (let i = 0; i < m; i++) {
cnt[arr[i]]++;
}
let check = (time) => {
let free = 0, needed = 0;
for (let i = 1; i <= n; i++) {
if (time >= cnt[i]) {
let extraTime = (time - cnt[i]);
free += Math.floor(extraTime / 2);
}
else {
needed += cnt[i] - time;
}
}
return needed <= free;
};
let l = 0, r = 2 * m;
let minTime = -1;
while (l <= r) {
let m = Math.floor((l + r) / 2);
if (check(m)) {
minTime = m;
r = m - 1;
}
else {
l = m + 1;
}
}
console.log(minTime);
}
let n = 2, m = 4;
let arr = [1, 2, 1, 2];
minTimeRequired(n, m, arr);
|
Time Complexity: O(n*logm)
Auxiliary Space: O(n)
Related Articles:
Last Updated :
22 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...