Given an array arr[] of size N, and integers K and D, consisting of breakpoints in journey, the task is to find the distance covered after the last breakpoint with at most K cost following the given conditions:
- Starting point is 0
- 1 unit distance is covered for 1 cost.
- For moving D continuous distance there is an extra cost of D i.e., total cost becomes D*1 + D = 2D.
Note: If N = 0 that means there is no breakpoint and starting is from 0.
Examples:
Input: arr[] = {17, 12, 18}, K = 28, D = 8
Output: 2
Explanation: Movement from 0 to 8. Covered distance cost = 8*1 + 8 = 16
Movement from 8 to 12 as 12 is a break point. Cost = 12 – 8 = 4. Total cost = 16 + 4 = 20.
Movement from 12 to 17. Cost = 17 – 12 = 5. Total cost = 20 + 5 = 25.
Movement from 17 to 18. Cost = 18 – 17 = 1. Total Cost = 26.
Remaining cost = 2.
So extra distance that can be covered after last breakpoint(18) = 2.Input: arr[] = {}, K = 100, D = 8
Output: 52
Explanation: Movement from 0 to 8. Distance = 8. Cost = 8*1 + 8 = 16. Total = 16
Movement from 8 to 16. Distance = 8. Cost = 8*1 + 8 = 16. Total = 32.
Movement from 16 to 24. Distance = 8. Cost = 8*1 + 8 = 16. Total = 48.
Movement from 24 to 32. Distance = 8. Cost = 8*1 + 8 = 16. Total = 64.
Movement from 32 to 40. Distance = 8. Cost = 8*1 + 8 = 16. Total = 80.
Movement from 40 to 48. Distance = 8. Cost = 8*1 + 8 = 16. Total = 96.
Movement from 48 to 52. Distance = 4. Cost = 4*1 = 4. Total = 100.
Distance covered after last breakpoint (no breakpoint here)= 52.
Approach: The given problem can be solved based on the following mathematical observation:
Distance between two consecutive breakpoints X and Y is (X – Y).
The number of times D consecutive movements are made = floor((X – Y)/D).
The cost for these consecutive movements is 2*D * floor((X-Y)/D).
Say M cost is paid to reach the last breakpoint.
Then the extra D consecutive distances that can be covered is floor((K – M)/2*D).
The cost for this is D* floor((K – M)/2*D). If the remaining cost is > D then only D additional distance can be covered.
Follow the steps to solve the problem:
- First check for Edge Case N = 0
- If N!=0 then sort the given breakpoints.
- Calculate the distance from the 1st point to 0th point.
- Traverse the array from i = 1 to N – 1.
- Calculate the distance between arr[i] and arr[i-1].
- Calculate the cost to cover this distance (say Count).
- If, K<= Count, return 0
- Calculate the extra distance by using the above observation:
- Res = D*(( K – Count) / (2*D) ) (number of times consecutive D distances covered)
- Rem = (K – Count) % (2*D) (Remaining cost)
- If, Rem >= D && Rem <=(2*D-1) then Rem = D
- Return, Res + Rem as the final extra distance covered.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to return total extra distance // covered using the cost K int countDays( int * arr, int N, int K, int D)
{ // Edge Case
if (N == 0) {
int Res = D * (K / (2 * D));
int Rem = K % (2 * D);
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
return (Res + Rem);
}
// Sort the array
sort(arr, arr + N);
// Count the points from the
// first point to 0th index point
int Count = 2 * D * (arr[0] / D)
+ arr[0] % D;
int Curr = 0;
// Traverse the array
for ( int i = 1; i < N; i++) {
// If there is not
// any breakpoint alternately
if ((arr[i] - arr[i - 1]) >= 1) {
// Distance between
// arr[i] and arr[i-1]
Curr = arr[i] - arr[i - 1];
// Cost between arr[i] and arr[i-1]
Count += 2 * D * (Curr / D)
+ (Curr % D);
}
}
// Cost to move till last point
if (K <= Count)
return 0;
// Calculate extra distance travelled
int Res = D * ((K - Count) / (2 * D));
int Rem = (K - Count) % (2 * D);
// D extra cost for D consecutive distance
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
// Return extra distance
return (Res + Rem);
} // Driver Code int main()
{ int arr[] = { 17, 12, 18 };
int D = 8;
int N = sizeof (arr) / sizeof (arr[0]);
int K = 28;
// Function call
cout << countDays(arr, N, K, D);
return 0;
} |
// JAVA program for the above approach import java.util.*;
class GFG
{ // Function to return total extra distance
// covered using the cost K
public static int countDays( int arr[], int N, int K,
int D)
{
// Edge Case
if (N == 0 ) {
int Res = D * (K / ( 2 * D));
int Rem = K % ( 2 * D);
if (Rem >= D && Rem <= ( 2 * D - 1 ))
Rem = D;
return (Res + Rem);
}
// Sort the array
Arrays.sort(arr);
// Count the points from the
// first point to 0th index point
int Count = 2 * D * (arr[ 0 ] / D) + arr[ 0 ] % D;
int Curr = 0 ;
// Traverse the array
for ( int i = 1 ; i < N; i++) {
// If there is not
// any breakpoint alternately
if ((arr[i] - arr[i - 1 ]) >= 1 ) {
// Distance between
// arr[i] and arr[i-1]
Curr = arr[i] - arr[i - 1 ];
// Cost between arr[i] and arr[i-1]
Count += 2 * D * (Curr / D) + (Curr % D);
}
}
// Cost to move till last point
if (K <= Count)
return 0 ;
// Calculate extra distance travelled
int Res = D * ((K - Count) / ( 2 * D));
int Rem = (K - Count) % ( 2 * D);
// D extra cost for D consecutive distance
if (Rem >= D && Rem <= ( 2 * D - 1 ))
Rem = D;
// Return extra distance
return (Res + Rem);
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 17 , 12 , 18 };
int D = 8 ;
int N = arr.length;
int K = 28 ;
// Function call
System.out.print(countDays(arr, N, K, D));
}
} // This code is contributed by Taranpreet |
# Python program for the above approach # Function to return total extra distance # covered using the cost K def countDays(arr, N, K, D):
# Edge Case
if (N = = 0 ):
Res = D * (K / / ( 2 * D))
Rem = K % ( 2 * D)
if (Rem > = D and Rem < = ( 2 * D - 1 )):
Rem = D
return (Res + Rem)
# Sort the array
arr.sort()
# Count the points from the
# first point to 0th index point
Count = 2 * D * (arr[ 0 ] / / D) + arr[ 0 ] % D
Curr = 0
# Traverse the array
for i in range ( 1 , N):
# If there is not
# any breakpoint alternately
if ((arr[i] - arr[i - 1 ]) > = 1 ):
# Distance between
# arr[i] and arr[i-1]
Curr = arr[i] - arr[i - 1 ]
# Cost between arr[i] and arr[i-1]
Count + = 2 * D * (Curr / / D) + (Curr % D)
# Cost to move till last point
if (K < = Count):
return 0
# Calculate extra distance travelled
Res = D * ((K - Count) / / ( 2 * D))
Rem = (K - Count) % ( 2 * D)
# D extra cost for D consecutive distance
if ((Rem > = D) and Rem < = ( 2 * D - 1 )):
Rem = D
# Return extra distance
return (Res + Rem)
# Driver Code if __name__ = = "__main__" :
arr = [ 17 , 12 , 18 ]
D = 8
N = len (arr)
K = 28
# Function call
print (countDays(arr, N, K, D))
# This code is contributed by hrithikgarg03188.
|
// C# program for the above approach using System;
class GFG {
// Function to return total extra distance
// covered using the cost K
static int countDays( int [] arr, int N, int K, int D)
{
int Rem = 0, Res = 0;
// Edge Case
if (N == 0) {
Res = D * (K / (2 * D));
Rem = K % (2 * D);
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
return (Res + Rem);
}
// Sort the array
Array.Sort(arr);
// Count the points from the
// first point to 0th index point
int Count = 2 * D * (arr[0] / D) + arr[0] % D;
int Curr = 0;
// Traverse the array
for ( int i = 1; i < N; i++) {
// If there is not
// any breakpoint alternately
if ((arr[i] - arr[i - 1]) >= 1) {
// Distance between
// arr[i] and arr[i-1]
Curr = arr[i] - arr[i - 1];
// Cost between arr[i] and arr[i-1]
Count += 2 * D * (Curr / D) + (Curr % D);
}
}
// Cost to move till last point
if (K <= Count)
return 0;
// Calculate extra distance travelled
Res = D * ((K - Count) / (2 * D));
Rem = (K - Count) % (2 * D);
// D extra cost for D consecutive distance
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
// Return extra distance
return (Res + Rem);
}
// Driver Code
public static void Main()
{
int [] arr = { 17, 12, 18 };
int D = 8;
int N = arr.Length;
int K = 28;
// Function call
Console.Write(countDays(arr, N, K, D));
}
} // This code is contributed by Taranpreet |
<script> // JavaScript program for the above approach
// Function to return total extra distance
// covered using the cost K
const countDays = (arr, N, K, D) => {
// Edge Case
if (N == 0) {
let Res = D * parseInt(K / (2 * D));
let Rem = K % (2 * D);
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
return (Res + Rem);
}
// Sort the array
arr.sort();
// Count the points from the
// first point to 0th index point
let Count = 2 * D * parseInt(arr[0] / D)
+ arr[0] % D;
let Curr = 0;
// Traverse the array
for (let i = 1; i < N; i++) {
// If there is not
// any breakpoint alternately
if ((arr[i] - arr[i - 1]) >= 1) {
// Distance between
// arr[i] and arr[i-1]
Curr = arr[i] - arr[i - 1];
// Cost between arr[i] and arr[i-1]
Count += 2 * D * parseInt(Curr / D)
+ (Curr % D);
}
}
// Cost to move till last point
if (K <= Count)
return 0;
// Calculate extra distance travelled
let Res = D * parseInt((K - Count) / (2 * D));
let Rem = (K - Count) % (2 * D);
// D extra cost for D consecutive distance
if (Rem >= D && Rem <= (2 * D - 1))
Rem = D;
// Return extra distance
return (Res + Rem);
}
// Driver Code
let arr = [17, 12, 18];
let D = 8;
let N = arr.length;
let K = 28;
// Function call
document.write(countDays(arr, N, K, D));
// This code is contributed by rakeshsahni </script> |
2
Time Complexity: O(N * logN)
Auxiliary Space: O(1)