Consider a pipe of length L. The pipe has N water droplets at N different positions within it. Each water droplet is moving towards the end of the pipe(x=L) at different rates. When a water droplet mixes with another water droplet, it assumes the speed of the water droplet it is mixing with. Determine the no of droplets that come out of the end of the pipe.
Refer to the figure below:
The numbers on circles indicates speed of water droplets
Examples:
Input: length = 12, position = [10, 8, 0, 5, 3],
speed = [2, 4, 1, 1, 3]
Output: 3
Explanation:
Droplets starting at x=10 and x=8 become a droplet,
meeting each other at x=12 at time =1 sec.
The droplet starting at 0 doesn't mix with any
other droplet, so it is a drop by itself.
Droplets starting at x=5 and x=3 become a single
drop, mixing with each other at x=6 at time = 1 sec.
Note that no other droplets meet these drops before
the end of the pipe, so the answer is 3.
Refer to the figure below
Numbers on circles indicates speed of water droplets.
Approach:
This problem uses greedy technique.
A drop will mix with another drop if two conditions are met:
- 1. If the drop is faster than the drop it is mixing with
- If the position of the faster drop is behind the slower drop.
We use an array of pairs to store the position and the time that ith drop would take to reach the end of the pipe. Then we sort the array according to the position of the drops. Now we have a fair idea of which drops lie behind which drops and their respective time taken to reach the end. More time means less speed and less time means more speed. Now all the drops before a slower drop will mix with it. And all the drops after the slower drop with mix with the next slower drop and so on.
For example, if the times to reach the end are: 12, 3, 7, 8, 1 (sorted according to positions)
0th drop is slowest, it won’t mix with the next drop
1st drop is faster than the 2nd drop, So they will mix and 2nd drop is faster than the third drop so all three will mix together. They cannot mix with the 4th drop because that is faster.
No of local maximal + residue(drops after last local maxima) = Total number of drops.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int drops( int length, int position[],
int speed[], int n)
{
vector<pair< int , double > > m(n);
int i;
for (i = 0; i < n; i++) {
int p = length - position[i];
m[i].first = position[i];
m[i].second = p * 1.0 / speed[i];
}
sort(m.begin(), m.end());
int k = 0;
int curr_max = m[n-1].second;
for (i = n - 2; i >= 0; i--)
{
if (m[i].second > curr_max)
{
k++;
curr_max=m[i].second;
}
}
k++;
return k;
}
int main()
{
int length = 12;
int position[] = { 10, 8, 0, 5, 3 };
int speed[] = { 2, 4, 1, 1, 3 };
int n = sizeof (speed)/ sizeof (speed[0]);
cout << drops(length, position, speed, n);
return 0;
}
|
Java
import java.util.*;
class Pair {
int x;
int y;
public Pair( int x, int y)
{
this .x = x;
this .y = y;
}
}
class Compare {
static void compare(Pair arr[], int n)
{
Arrays.sort(arr, new Comparator<Pair>() {
@Override public int compare(Pair p1, Pair p2)
{
return p1.x - p2.x;
}
});
}
}
public class Main
{
static int drops( int length, int [] position, int [] speed, int n)
{
Pair m[] = new Pair[n];
int i;
for (i = 0 ; i < n; i++)
{
int p = length - position[i];
m[i] = new Pair(position[i], p / speed[i]);
}
Compare obj = new Compare();
obj.compare(m, n);
int k = 0 ;
int curr_max = ( int )(m[n - 1 ].y);
for (i = n - 2 ; i >= 0 ; i--)
{
if (m[i].y > curr_max)
{
k++;
curr_max = ( int )(m[i].y);
}
}
k++;
return k;
}
public static void main(String[] args) {
int length = 12 ;
int [] position = { 10 , 8 , 0 , 5 , 3 };
int [] speed = { 2 , 4 , 1 , 1 , 3 };
int n = speed.length;
System.out.println(drops(length, position, speed, n));
}
}
|
Python3
def drops(length, position, speed, n):
m = []
for i in range (n):
p = length - position[i]
m.append([position[i], (p * 1.0 ) / speed[i]])
m.sort()
k = 0
curr_max = m[n - 1 ][ 1 ]
for i in range (n - 2 , - 1 , - 1 ):
if (m[i][ 1 ] > curr_max):
k + = 1
curr_max = m[i][ 1 ]
k + = 1
return k
length = 12
position = [ 10 , 8 , 0 , 5 , 3 ]
speed = [ 2 , 4 , 1 , 1 , 3 ]
n = len (speed)
print (drops(length, position, speed, n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int drops( int length, int [] position,
int [] speed, int n)
{
List<Tuple< int , double >> m = new List<Tuple< int , double >>();
int i;
for (i = 0; i < n; i++)
{
int p = length - position[i];
m.Add( new Tuple< int , double >(position[i], p * 1.0 / speed[i]));
}
m.Sort();
int k = 0;
int curr_max = ( int )m[n - 1].Item2;
for (i = n - 2; i >= 0; i--)
{
if (m[i].Item2 > curr_max)
{
k++;
curr_max = ( int )m[i].Item2;
}
}
k++;
return k;
}
static void Main()
{
int length = 12;
int [] position = { 10, 8, 0, 5, 3 };
int [] speed = { 2, 4, 1, 1, 3 };
int n = speed.Length;
Console.WriteLine(drops(length, position, speed, n));
}
}
|
Javascript
<script>
function drops(length, position, speed, n)
{
var m = Array.from(Array(n), ()=>Array(2));
var i;
for (i = 0; i < n; i++) {
var p = length - position[i];
m[i][0] = position[i];
m[i][1] = p * 1.0 / speed[i];
}
m.sort();
var k = 0;
var curr_max = m[n-1][1];
for (i = n - 2; i >= 0; i--)
{
if (m[i][1] > curr_max)
{
k++;
curr_max=m[i][1];
}
}
k++;
return k;
}
var length = 12;
var position = [10, 8, 0, 5, 3];
var speed = [2, 4, 1, 1, 3];
var n = speed.length;
document.write( drops(length, position, speed, n));
</script>
|
Complexity Analysis:
- Time Complexity: O(nlog(n))
- Auxiliary Space: O(n)
Last Updated :
26 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...