Number of circular tours that visit all petrol pumps

Suppose there is a circular road. There are n petrol pumps on that road. You are given two array, a[] and b[], and a positive integer c. where a[i] denote the amount of fuel we get on reaching ith petrol pump, b[i] denote the amount of fuel used to travel from ith petrol pump to (i + 1)th petrol pump and c denotes the capacity of the tank in the vehicle. The task is to calculate the number of petrol pump from where the vehicle will be able to complete the circle and come back to starting point.
This post is different from Find the first circular tour that visits all petrol pumps.
Examples:

Input : n = 3, c = 3
a[] = { 3, 1, 2 }
b[] = { 2, 2, 2 }
Output : 2
Explanation:
If we starts with 0th petrol pump, we will gain
3 (a[0]) litres of petrol and lose 2 litre (b[0] to travel
to 1st petrol pump.On refueling 1 litre (a[1])
of petrol on 1st petrol pump, we will lose 2
litres (b[0]) of petrol to reach 2nd petrol pump.
Now the tank is empty.On refueling 2 litres (a[2]) of petrol
at 2nd petrol pump, we can travel back 0th
petrol pump.

If we starts from 1st petrol pump, we will gain 1
litre of petrol but to travel to 2nd petrol pump
we need 2 litres of petrol, which we don’t have. So, we cannot
starts from 1st petrol pump.



If we starts from 2nd petrol pump, we will gain 2
litres of petrol and travel to 0th petrol pump by
losing 2 litres of petrol. On refueling 3 litres on 1st
petrol pump, we can travel to 1st petrol
pump by losing 2 litre petrol. On refueling 1 litre of petrol, we
will have 2 litres of petrol left which we can use by traveling to
2nd petrol pump.

Input : n = 3, c = 3
a[] = { 3, 1, 2 }
b[] = { 2, 2, 1 }
Output : 2

Approach:
The problem involves 2 parts, first involves if a valid starting petrol pump exists and second, if such a petrol pump exists, check if the petrol pump before it can also be used as a starting petrol pump.

First, lets start from a petrol pump s and travel to petrol pump, s + 1, s + 2, s + 3 till s + j, suppose we run out of fuel before we go to petrol pump s + j + 1, then no petrol pump between s and s + j can be used as starting petrol pump. Hence, we start over with s + j + 1 as the starting petrol pump. If no such petrol pump exists after all petrol pumps are exhausted, the answer is 0. This step takes O(n).

Second, lets visit one such valid petrol pump (lets call it s). The petrol pump before s i.e s – 1 can also be a start petrol pump provided the vehicle can start at s – 1 and reach s.

If a[i] is take fuel available at petrol pump i, and c be the capacity of the fuel tank, and b[i] is the amount of fuel the vehicle takes to travel from petrol pump i to i + 1, then lets define need[i] as follows:

need[i] = max(0, need[i + 1] + b[i] - min(c, a[i]))

need[i] is the extra fuel, if present in the vehicle at the beginning of the journey at petrol pump i (excluding a[i]_, it can be a valid petrol pump.

If need[i] = 0, then petrol pump i is a valid starting petrol pump. We know that need[s] = 0 from step 1. We can evaluate if s – 1, s – 2, … are starting petrol pumps are not. This step also takes O(n).

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find the number of
// circular tour that visits all petrol pump
#include <bits/stdc++.h>
using namespace std;
#define N 100
  
// Return the number of pumps from where we
// can start the journey.
int count(int n, int c, int a[], int b[])
{
    int need[N];
  
    // Making Circular Array.
    for (int i = 0; i < n; i++) {
        a[i + n] = a[i];
        b[i + n] = b[i];
    }
  
    int s = 0;
    int tank = 0;
  
    // for each of the petrol pump.
    for (int i = 0; i < 2 * n; i++) {
        tank += a[i];
        tank = min(tank, c);
        tank -= b[i];
  
        // If tank is less than 0.
        if (tank < 0) {
            tank = 0;
            s = i + 1;
        }
    }
  
    // If starting pump is greater than n,
    // return ans as 0.
    if (s >= n)
        return 0;
  
    int ans = 1;
    need[s + n] = 0;
  
    // For each of the petrol pump
    for (int i = 1; i < n; i++) {
        int id = s + n - i;
  
        // Finding the need array
        need[id] = max(0, need[id + 1] + b[id]
                              - min(a[id], c));
  
        // If need is 0, increment the count.
        if (need[id] == 0)
            ans++;
    }
  
    return ans;
}
  
// Drivers code
int main()
{
    int n = 3;
    int c = 3;
    int a[2 * N] = { 3, 1, 2 };
    int b[2 * N] = { 2, 2, 2 };
  
    cout << count(n, c, a, b) << endl;
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to find the number of 
// circular tour that visits all petrol pump 
import java.io.*;
  
class GFG 
    static int N = 100
  
    // Return the number of pumps from where we 
    // can start the journey. 
    public static int count(int n, int c, int a[], int b[]) 
    
        int need[] = new int[N]; 
      
        // Making Circular Array. 
        for (int i = 0; i < n; i++)
        
            a[i + n] = a[i]; 
            b[i + n] = b[i]; 
        
      
        int s = 0
        int tank = 0
      
        // for each of the petrol pump. 
        for (int i = 0; i < 2 * n; i++) 
        
            tank += a[i]; 
            tank = Math.min(tank, c); 
            tank -= b[i]; 
      
            // If tank is less than 0. 
            if (tank < 0
            
                tank = 0
                s = i + 1
            
        
      
        // If starting pump is greater
        //  than n, return ans as 0. 
        if (s >= n) 
            return 0
      
        int ans = 1
        need[s + n] = 0
      
        // For each of the petrol pump 
        for (int i = 1; i < n; i++) 
          
        
            int id = s + n - i; 
      
            // Finding the need array 
            need[id] = Math.max(0, need[id + 1] + b[id] 
                                - Math.min(a[id], c)); 
      
            // If need is 0, increment the count. 
            if (need[id] == 0
                ans++; 
        
      
        return ans; 
    
      
    // Driver code 
    public static void main(String args[]) 
    
        int n = 3
        int c = 3
        int[] a = new int[]{ 3, 1, 2, 0, 0, 0 }; 
        int[] b = new int[]{ 2, 2, 2, 0, 0, 0 }; 
      
        System.out.print(count(n, c, a, b) + "\n"); 
    }
}
  
// This code is contributed
// by Akanksha Rai

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 Program to find the number of
# circular tour that visits all petrol pump
N = 100
  
# Return the number of pumps from
# where we can start the journey.
def count(n, c, a, b):
    need = [0 for i in range(N)]
  
    # Making Circular Array.
    for i in range(0, n, 1):
        a[i + n] = a[i]
        b[i + n] = b[i]
  
    s = 0
    tank = 0
  
    # for each of the petrol pump.
    for i in range(0, 2 * n, 1):
        tank += a[i]
        tank = min(tank, c)
        tank -= b[i]
  
        # If tank is less than 0.
        if (tank < 0):
            tank = 0
            s = i + 1
          
    # If starting pump is greater 
    # than n, return ans as 0.
    if (s >= n):
        return 0
  
    ans = 1
    need[s + n] = 0
  
    # For each of the petrol pump
    for i in range(1, n, 1):
        id = s + n - i
  
        # Finding the need array
        need[id] = max(0, need[id + 1] + 
                     b[id] - min(a[id], c))
  
        # If need is 0, increment the count.
        if (need[id] == 0):
            ans += 1
  
    return ans
  
# Driver Code
if __name__ == '__main__':
    n = 3
    c = 3
    a = [3, 1, 2, 0, 0, 0]
    b = [2, 2, 2, 0, 0, 0]
  
    print(count(n, c, a, b))
  
# This code is contributed by
# Sahil_Shelangia

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to find the number of 
// circular tour that visits all petrol pump 
using System; 
    
class GFG 
    static int N = 100; 
    
    // Return the number of pumps from where we 
    // can start the journey. 
    public static int count(int n, int c, int[] a, int[] b) 
    
        int[] need = new int[N]; 
        
        // Making Circular Array. 
        for (int i = 0; i < n; i++) { 
            a[i + n] = a[i]; 
            b[i + n] = b[i]; 
        
        
        int s = 0; 
        int tank = 0; 
        
        // for each of the petrol pump. 
        for (int i = 0; i < 2 * n; i++) { 
            tank += a[i]; 
            tank = Math.Min(tank, c); 
            tank -= b[i]; 
        
            // If tank is less than 0. 
            if (tank < 0) { 
                tank = 0; 
                s = i + 1; 
            
        
        
        // If starting pump is greater than n, 
        // return ans as 0. 
        if (s >= n) 
            return 0; 
        
        int ans = 1; 
        need[s + n] = 0; 
        
        // For each of the petrol pump 
        for (int i = 1; i < n; i++) { 
            int id = s + n - i; 
        
            // Finding the need array 
            need[id] = Math.Max(0, need[id + 1] + b[id] 
                                  - Math.Min(a[id], c)); 
        
            // If need is 0, increment the count. 
            if (need[id] == 0) 
                ans++; 
        
        
        return ans; 
    
        
    // Drivers code 
    static void Main() 
    
        int n = 3; 
        int c = 3; 
        int[] a = new int[6]{ 3, 1, 2, 0, 0, 0 }; 
        int[] b = new int[6]{ 2, 2, 2, 0, 0, 0 }; 
        
        Console.Write(count(n, c, a, b) + "\n"); 
    }
    //This code is contributed by DrRoot_
}

chevron_right


Output:

2

Time Complexity: O(n)

Reference:
https://stackoverflow.com/questions/24408371/dynamic-programming-find-possible-ways-to-reach-destination



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.