最后一个断点后覆盖的距离,最多 K 成本
给定一个大小为N的数组arr[]和整数K和D ,由旅程中的断点组成,任务是在给定条件下以最多K成本找到最后一个断点之后所覆盖的距离:
- 起点为0
- 1 个单位距离覆盖 1 个成本。
- 对于移动 D 连续距离,有额外的 D 成本,即总成本变为 D*1 + D = 2D。
注意:如果 N = 0 表示没有断点并且从 0 开始。
例子:
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.
方法:给定的问题可以基于以下数学观察来解决:
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.
请按照以下步骤解决问题:
- 首先检查边缘情况N = 0
- 如果N!=0则对给定的断点进行排序。
- 计算从第1点到第 0点的距离。
- 从i = 1到N – 1 遍历数组。
- 计算arr[i]和arr[i-1]之间的距离。
- 计算覆盖此距离的成本(例如Count )。
- 如果, K<= Count ,返回0
- 使用上述观察计算额外距离:
- Res = D*(( K – Count) / (2*D) ) (连续 D 距离覆盖的次数)
- Rem = (K – 计数) % (2*D) (剩余成本)
- 如果, Rem >= D && Rem <=(2*D-1)那么Rem = D
- Return, Res + Rem作为最后的额外距离。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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
// 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
Python3
# 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#
// 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
Javascript
2
时间复杂度:O(N * logN)
辅助空间:O(1)