Time Crunch Challenge
Last Updated :
04 Dec, 2023
Geeks for Geeks is organizing a hackathon consisting of N sections, each containing K questions. The duration of the hackathon is H hours.
Each participant can determine their speed of solving questions, denoted as S (S = questions-per-hour). During each hour, a participant can choose a section and solve S problems. If a section has fewer than S questions, the participant will not solve any additional questions from that section during that hour.
The goal is for the participant to solve the questions at a slower pace while still completing all the questions before the hackathon ends, the task is to find the S such that ensures the participant will solve all the questions within H hours.
Examples:
Input: section = [ 2, 4, 2, 4, 5], H = 8
Output: 3
Explanation: Participate will solve 3 questions per hour to solve all the questions within 8 hours.
Input: section = [ 8, 11, 18, 20], H = 10
Output: 7
Explanation: Participate will solve 7 questions per hour to solve all the questions within 10 hours.
Naïve Approach: The basic way to solve the problem is as follows:
- Check if
H
is equal to the number of sections.
- If true, return the maximum time needed for any section.
- Calculate the minimum possible solving speed (k_min) by dividing the total time required to solve all sections by
H
.
- Calculate the maximum possible solving speed (k_max) by finding the maximum time needed for any section using
max_element
.
- Iterate through possible solving speeds from
k_min
to k_max
.
- Calculate the total hours required to solve all sections at each speed.
- If total hours are equal
H
, return the current speed k
.
- If no valid solution is found, return -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public :
int minSolvingSpeed(vector< int >& sections, int h)
{
if (h == sections.size()) {
return *max_element(sections.begin(),
sections.end());
}
int k_min
= ceil ( static_cast < double >(accumulate(
sections.begin(), sections.end(), 0))
/ h);
int k_max = *max_element(sections.begin(),
sections.end());
for ( int k = k_min; k <= k_max; k++) {
int hours_to_solve = 0;
for ( int section : sections) {
hours_to_solve += ceil (
static_cast < double >(section) / k);
}
if (hours_to_solve == h) {
return k;
}
}
return -1;
}
};
int main()
{
Solution solution;
vector< int > sections = { 8, 11, 18, 20 };
int h = 10;
int result = solution.minSolvingSpeed(sections, h);
cout << "Minimum eating speed required: " << result
<< endl;
return 0;
}
|
Java
import java.util.*;
class Solution {
public int minSolvingSpeed(List<Integer> sections, int h) {
if (h == sections.size()) {
return Collections.max(sections);
}
int k_min = ( int ) Math.ceil(sections.stream().mapToDouble(Integer::doubleValue).sum() / h);
int k_max = Collections.max(sections);
for ( int k = k_min; k <= k_max; k++) {
int hours_to_solve = 0 ;
for ( int section : sections) {
hours_to_solve += Math.ceil(( double ) section / k);
}
if (hours_to_solve == h) {
return k;
}
}
return - 1 ;
}
}
public class Main {
public static void main(String[] args) {
Solution solution = new Solution();
List<Integer> sections = Arrays.asList( 8 , 11 , 18 , 20 );
int h = 10 ;
int result = solution.minSolvingSpeed(sections, h);
System.out.println( "Minimum eating speed required: " + result);
}
}
|
Python3
class Solution:
def min_solving_speed( self , sections, h):
if h = = len (sections):
return max (sections)
k_min = - ( - sum (sections) / / h)
k_max = max (sections)
for k in range (k_min, k_max + 1 ):
hours_to_solve = 0
for section in sections:
hours_to_solve + = - ( - section / / k)
if hours_to_solve = = h:
return k
return - 1
if __name__ = = "__main__" :
solution = Solution()
sections = [ 8 , 11 , 18 , 20 ]
h = 10
result = solution.min_solving_speed(sections, h)
print ( "Minimum eating speed required:" , result)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution
{
public int MinSolvingSpeed(List< int > sections, int h)
{
if (h == sections.Count)
{
return sections.Max();
}
int k_min = ( int )Math.Ceiling(( double )sections.Sum() / h);
int k_max = sections.Max();
for ( int k = k_min; k <= k_max; k++)
{
int hoursToSolve = 0;
foreach ( int section in sections)
{
hoursToSolve += ( int )Math.Ceiling(( double )section / k);
}
if (hoursToSolve == h)
{
return k;
}
}
return -1;
}
}
class Program
{
static void Main()
{
Solution solution = new Solution();
List< int > sections = new List< int > { 8, 11, 18, 20 };
int h = 10;
int result = solution.MinSolvingSpeed(sections, h);
Console.WriteLine( "Minimum eating speed required: " + result);
}
}
|
Javascript
class Solution {
minSolvingSpeed(sections, h) {
if (h === sections.length) {
return Math.max(...sections);
}
const k_min = Math.ceil(sections.reduce((acc, section) => acc + section, 0) / h);
const k_max = Math.max(...sections);
for (let k = k_min; k <= k_max; k++) {
let hours_to_solve = 0;
for (let i = 0; i < sections.length; i++) {
hours_to_solve += Math.ceil(sections[i] / k);
}
if (hours_to_solve === h) {
return k;
}
}
return -1;
}
}
const solution = new Solution();
const sections = [8, 11, 18, 20];
const h = 10;
const result = solution.minSolvingSpeed(sections, h);
console.log( "Minimum eating speed required: " + result);
|
Output
Minimum eating speed required: 7
Time Complexity: O(n (max K −min K))
Auxiliary Space: O(1)
Efficient Approach: To solve the problem follow the below idea:
We can solve this problem using Binary Search
Follow the below steps to solve the problem:
- Initialize the left pointer to 1 and the right pointer to the maximum value in the section vector.
- While the left pointer is less than the right pointer, repeat steps 3-5.
- Calculate the midpoint as the average of the left and right pointers.
- Check if the participant can solve all the questions within h hours at the current midpoint speed using the canSolveAll function. If true, update the right pointer to the midpoint. Otherwise, update the left pointer to midpoint + 1.
- Repeat steps 3-4 until the left pointer becomes equal to the right pointer.
- Return the left pointer as the minimum solving speed required to solve all the questions within H hours.
- we get then our final result.
Below is the implementation of the above approach:
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool canSolveAll(vector< int >& sections, int speed, int h)
{
int time = 0;
for ( int section : sections) {
time += (section - 1) / speed + 1;
if ( time > h) {
return false ;
}
}
return true ;
}
int minSolvingSpeed(vector< int >& sections, int h)
{
int left = 1;
int right
= *max_element(sections.begin(), sections.end());
while (left < right) {
int mid = (left + right) / 2;
if (canSolveAll(sections, mid, h)) {
right = mid;
}
else {
left = mid + 1;
}
}
return left;
}
int main()
{
vector< int > sectionss = { 8, 11, 18, 20 };
int H = 10;
cout << minSolvingSpeed(sectionss, H);
return 0;
}
|
Java
import java.util.*;
class Main {
static boolean canSolveAll(List<Integer> sections, int speed, int h) {
int time = 0 ;
for ( int section : sections) {
time += (section - 1 ) / speed + 1 ;
if (time > h) {
return false ;
}
}
return true ;
}
static int minSolvingSpeed(List<Integer> sections, int h) {
int left = 1 ;
int right = Collections.max(sections);
while (left < right) {
int mid = (left + right) / 2 ;
if (canSolveAll(sections, mid, h)) {
right = mid;
} else {
left = mid + 1 ;
}
}
return left;
}
public static void main(String[] args) {
List<Integer> sections = Arrays.asList( 8 , 11 , 18 , 20 );
int H = 10 ;
int result = minSolvingSpeed(sections, H);
System.out.println( "Minimum eating speed required: " + result);
}
}
|
Python
def can_solve_all(sections, speed, h):
time = 0
for section in sections:
time + = (section - 1 ) / / speed + 1
if time > h:
return False
return True
def min_solving_speed(sections, h):
left = 1
right = max (sections)
while left < right:
mid = (left + right) / / 2
if can_solve_all(sections, mid, h):
right = mid
else :
left = mid + 1
return left
def main():
sections = [ 8 , 11 , 18 , 20 ]
H = 10
print (min_solving_speed(sections, H))
if __name__ = = "__main__" :
main()
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static bool CanSolveAll(List< int > sections, int speed, int h)
{
int time = 0;
foreach ( int section in sections)
{
time += (section - 1) / speed + 1;
if (time > h)
{
return false ;
}
}
return true ;
}
static int MinSolvingSpeed(List< int > sections, int h)
{
int left = 1;
int right = sections.Max();
while (left < right)
{
int mid = (left + right) / 2;
if (CanSolveAll(sections, mid, h))
{
right = mid;
}
else
{
left = mid + 1;
}
}
return left;
}
static void Main( string [] args)
{
List< int > sections = new List< int > { 8, 11, 18, 20 };
int H = 10;
Console.WriteLine(MinSolvingSpeed(sections, H));
}
}
|
Javascript
function canSolveAll(sections, speed, h) {
let time = 0;
for (let section of sections) {
time += Math.floor((section - 1) / speed) + 1;
if (time > h) {
return false ;
}
}
return true ;
}
function minSolvingSpeed(sections, h) {
let left = 1;
let right = Math.max(...sections);
while (left < right) {
let mid = Math.floor((left + right) / 2);
if (canSolveAll(sections, mid, h)) {
right = mid;
}
else {
left = mid + 1;
}
}
return left;
}
let sections = [8, 11, 18, 20];
let H = 10;
console.log(minSolvingSpeed(sections, H));
|
Time Complexity: O(n.logn)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...