Water drop problem - GeeksforGeeks

06 Oct, 2021
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 2. 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++
Java
Python3
C#
Javascript
#include <bits/stdc++.h>using namespace std; // Function to find the number// of the drops that come out of the// pipeint drops(int length, int position[],          int speed[], int n){       // stores position and time    // taken by a single    // drop to reach the end as a pair    vector<pair<int, double> > m(n);     int i;    for (i = 0; i < n; i++) {         // calculates distance needs to be        // covered by the ith drop        int p = length - position[i];         // inserts initial position of the        // ith drop to the pair         m[i].first = position[i];         // inserts time taken by ith        // drop to reach        // the end to the pair        m[i].second = p * 1.0 / speed[i];    }     // sorts the pair according to increasing    // order of their positions    sort(m.begin(), m.end());    int k = 0; // counter for no of final drops      int curr_max = m[n-1].second;    // we traverse the array demo    // right to left    // to determine the slower drop    for (i = n - 2; i >= 0; i--)    {        // checks for next slower drop        if (m[i].second > curr_max)        {            k++;              curr_max=m[i].second;        }    }     // calculating residual    // drops in the pipe    k++;    return k;} // Driver Codeint main(){    // length of pipe    int length = 12;       // position of droplets    int position[] = { 10, 8, 0, 5, 3 };       // speed of each droplets    int speed[] = { 2, 4, 1, 1, 3 };    int n = sizeof(speed)/sizeof(speed[0]);    cout << drops(length, position, speed, n);    return 0;}
import java.util.*; // User defined Pair classclass Pair {    int x;    int y;       // Constructor    public Pair(int x, int y)    {        this.x = x;        this.y = y;    }} // class to define user defined conparatorclass Compare {       static void compare(Pair arr[], int n)    {        // Comparator to sort the pair according to second element        Arrays.sort(arr, new Comparator<Pair>() {            @Override public int compare(Pair p1, Pair p2)            {                return p1.x - p2.x;            }        });    }} public class Main{    // Function to find the number  // of the drops that come out of the  // pipe  static int drops(int length, int[] position, int[] speed, int n)  {    // stores position and time    // taken by a single    // drop to reach the end as a pair    Pair m[] = new Pair[n];    int i;    for (i = 0; i < n; i++)    {        // calculates distance needs to be      // covered by the ith drop      int p = length - position[i];        // inserts initial position of the      // ith drop to the pair      // inserts time taken by ith      // drop to reach      // the end to the pair      m[i] = new Pair(position[i], p / speed[i]);    }      // sorts the pair according to increasing    // order of their positions    Compare obj = new Compare();    obj.compare(m, n);    int k = 0; // counter for no of final drops    int curr_max = (int)(m[n - 1].y);      // we traverse the array demo    // right to left    // to determine the slower drop    for (i = n - 2; i >= 0; i--)    {        // checks for next slower drop      if (m[i].y > curr_max)      {        k++;        curr_max = (int)(m[i].y);      }    }      // calculating residual    // drops in the pipe    k++;    return k;  }       public static void main(String[] args) {        // length of pipe        int length = 12;              // position of droplets        int[] position = { 10, 8, 0, 5, 3 };              // speed of each droplets        int[] speed = { 2, 4, 1, 1, 3 };        int n = speed.length;        System.out.println(drops(length, position, speed, n));    }} // This code is contributed by decode2207.
# Function to find the number# of the drops that come out of the# pipedef drops(length, position, speed, n):         # Stores position and time    # taken by a single drop to    # reach the end as a pair    m = []     for i in range(n):                 # Calculates distance needs to be        # covered by the ith drop        p = length - position[i]         # Inserts initial position of the        # ith drop to the pair        # inserts time taken by ith        # drop to reach        # the end to the pair        m.append([position[i], (p * 1.0) / speed[i]])     # Sorts the pair according to increasing    # order of their positions    m.sort()         # Counter for no of final drops    k = 0         curr_max = m[n - 1][1]         # We traverse the array demo    # right to left    # to determine the slower drop    for i in range(n - 2, -1, -1):                 # Checks for next slower drop        if (m[i][1] > curr_max):            k += 1            curr_max = m[i][1]                 # Calculating residual    # drops in the pipe    k += 1    return k     # Driver Code # Length of pipelength = 12 # Position of dropletsposition = [ 10, 8, 0, 5, 3 ] # Speed of each dropletsspeed = [ 2, 4, 1, 1, 3 ]n = len(speed) print(drops(length, position, speed, n)) # This code is contributed by divyeshrabadiya07
using System;using System.Collections.Generic;class GFG{   // Function to find the number  // of the drops that come out of the  // pipe  static int drops(int length, int[] position,                   int[] speed, int n)  {     // stores position and time    // taken by a single    // drop to reach the end as a pair    List<Tuple<int,double>> m = new List<Tuple<int,double>>();    int i;    for (i = 0; i < n; i++)    {       // calculates distance needs to be      // covered by the ith drop      int p = length - position[i];       // inserts initial position of the      // ith drop to the pair      // inserts time taken by ith      // drop to reach      // the end to the pair      m.Add(new Tuple<int,double>(position[i], p * 1.0 / speed[i]));    }     // sorts the pair according to increasing    // order of their positions    m.Sort();    int k = 0; // counter for no of final drops    int curr_max = (int)m[n - 1].Item2;     // we traverse the array demo    // right to left    // to determine the slower drop    for (i = n - 2; i >= 0; i--)    {       // checks for next slower drop      if (m[i].Item2 > curr_max)      {        k++;        curr_max = (int)m[i].Item2;      }    }     // calculating residual    // drops in the pipe    k++;    return k;  }   // Driver code  static void Main()  {     // length of pipe    int length = 12;     // position of droplets    int[] position = { 10, 8, 0, 5, 3 };     // speed of each droplets    int[] speed = { 2, 4, 1, 1, 3 };    int n = speed.Length;    Console.WriteLine(drops(length, position, speed, n));  }} // This code is contributed by divyesh072019
<script> // Function to find the number// of the drops that come out of the// pipefunction drops(length, position, speed, n){       // stores position and time    // taken by a single    // drop to reach the end as a pair    var m = Array.from(Array(n), ()=>Array(2));     var i;    for (i = 0; i < n; i++) {         // calculates distance needs to be        // covered by the ith drop        var p = length - position[i];         // inserts initial position of the        // ith drop to the pair         m[i][0] = position[i];         // inserts time taken by ith        // drop to reach        // the end to the pair        m[i][1] = p * 1.0 / speed[i];    }     // sorts the pair according to increasing    // order of their positions    m.sort();    var k = 0; // counter for no of final drops      var curr_max = m[n-1][1];    // we traverse the array demo    // right to left    // to determine the slower drop    for (i = n - 2; i >= 0; i--)    {        // checks for next slower drop        if (m[i][1] > curr_max)        {            k++;              curr_max=m[i][1];        }    }     // calculating residual    // drops in the pipe    k++;    return k;} // Driver Code// length of pipevar length = 12; // position of dropletsvar position = [10, 8, 0, 5, 3]; // speed of each dropletsvar speed = [2, 4, 1, 1, 3];var n = speed.length;document.write( drops(length, position, speed, n));  </script>
3
sasmitvaidya007
divyeshrabadiya07
divyesh072019
rutvik_56
decode2207
be1398
Competitive Programming
Greedy
Sorting
Stack
Greedy
Stack
Sorting
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Multistage Graph (Shortest Path)
Breadth First Traversal ( BFS ) on a 2D array
Difference between Backtracking and Branch-N-Bound technique
Most important type of Algorithms
5 Best Languages for Competitive Programming
Dijkstra's shortest path algorithm | Greedy Algo-7
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Program for array rotation
Write a program to print all permutations of a given string