Searching & SortingProblem 31 of 36
ROTI-Prata SPOJ
Problem Statement
IEEE wants to serve its members some delicious Indian food. A dish called "Prata" needs to be prepared. There are L cooks, each with a different cooking skill represented by a rank R. A cook with rank R can prepare:
- 1st prata in R minutes
- 2nd prata in 2R minutes
- 3rd prata in 3R minutes
- And so on...
Given the number of pratas P needed and the ranks of L cooks, find the minimum time required to prepare all P pratas.
Constraints:
- 1 ≤ P ≤ 1000
- 1 ≤ L ≤ 50
- 1 ≤ R ≤ 8
Example:
- Input:
P = 10,ranks = [1, 2, 3, 4] - Output:
12 - Explanation:
- Cook 1 (rank 1): pratas in 1, 2, 3, 4 min (4 pratas in 1+2+3+4=10 min)
- Cook 2 (rank 2): pratas in 2, 4 min (2 pratas in 2+4=6 min)
- Cook 3 (rank 3): pratas in 3, 6 min (2 pratas in 3+6=9 min)
- Cook 4 (rank 4): pratas in 4, 8 min (2 pratas in 4+8=12 min)
- Total: 4+2+2+2 = 10 pratas in 12 minutes
Example 2:
- Input:
P = 8,ranks = [1, 1] - Output:
10 - Explanation: Each cook makes 4 pratas in 1+2+3+4=10 minutes
Background: Time for K Pratas
For a cook with rank R:
- Time for k pratas = R×(1 + 2 + ... + k) = R × k(k+1)/2
Given time T and rank R, max pratas a cook can make:
- Find largest k such that R × k(k+1)/2 ≤ T
- This can be solved using quadratic formula
Approach 1: Brute Force (Simulation)
Intuition
Simulate the cooking process minute by minute, assigning pratas to available cooks.
Algorithm
- Start from time = 1
- At each time, check how many total pratas can be made
- Return first time where total pratas >= P
java
public class Solution {
private int maxPratasInTime(int rank, int time) {
double discriminant = 1 + 8.0 * time / rank;
return (int)((-1 + Math.sqrt(discriminant)) / 2);
}
private int totalPratasInTime(int[] ranks, int time) {
int total = 0;
for (int rank : ranks) {
total += maxPratasInTime(rank, time);
}
return total;
}
public int minTimeBrute(int P, int[] ranks) {
int time = 1;
while (totalPratasInTime(ranks, time) < P) {
time++;
}
return time;
}
}Complexity Analysis
- Time Complexity: O(P × maxTime) - Linear search up to answer
- Space Complexity: O(L) - For ranks array
Approach 2: Binary Search on Time (Optimal)
Intuition
The total number of pratas that can be made is monotonically increasing with time. This allows binary search on the time.
Key Observations:
- If we can make P pratas in time T, we can also make them in any time > T
- Minimum time = 1 (theoretical lower bound)
- Maximum time = when one cook makes all P pratas (worst case)
- Binary search for minimum time where total pratas >= P
Algorithm
- Calculate upper bound: time for worst cook to make all P pratas
- Binary search on time in range [1, upperBound]
- For each mid, calculate total pratas all cooks can make
- If >= P, try smaller time; else, increase time
java
import java.util.*;
public class RotiPrata {
private int maxPratasInTime(int rank, long time) {
double discriminant = 1.0 + 8.0 * time / rank;
return (int)((-1 + Math.sqrt(discriminant)) / 2);
}
private long totalPratasInTime(int[] ranks, long time) {
long total = 0;
for (int rank : ranks) {
total += maxPratasInTime(rank, time);
}
return total;
}
private long timeForKPratas(int rank, int k) {
return (long)rank * k * (k + 1) / 2;
}
public long minTime(int P, int[] ranks) {
int maxRank = 0;
for (int rank : ranks) {
maxRank = Math.max(maxRank, rank);
}
long high = timeForKPratas(maxRank, P);
long low = 1;
long result = high;
while (low <= high) {
long mid = low + (high - low) / 2;
if (totalPratasInTime(ranks, mid) >= P) {
result = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return result;
}
public static void main(String[] args) {
RotiPrata rp = new RotiPrata();
int[] ranks = {1, 2, 3, 4};
System.out.println(rp.minTime(10, ranks)); // Output: 12
}
}Dry Run Example
P = 10, ranks = [1, 2, 3, 4]
Upper bound: time_for_k_pratas(4, 10) = 4 * 10 * 11 / 2 = 220
low = 1, high = 220
Iteration 1:
mid = 110
For each cook, calculate max pratas in 110 min:
Rank 1: k = (-1 + sqrt(1 + 880)) / 2 ≈ 14.3 → 14 pratas
Rank 2: k = (-1 + sqrt(1 + 440)) / 2 ≈ 9.98 → 9 pratas
Rank 3: k = (-1 + sqrt(1 + 293)) / 2 ≈ 8.05 → 8 pratas
Rank 4: k = (-1 + sqrt(1 + 220)) / 2 ≈ 6.9 → 6 pratas
Total = 14 + 9 + 8 + 6 = 37 >= 10. Yes!
result = 110, high = 109
... (binary search continues)
Final iterations around answer:
mid = 12
Rank 1: k = (-1 + sqrt(1 + 96)) / 2 ≈ 4.4 → 4 pratas
Rank 2: k = (-1 + sqrt(1 + 48)) / 2 ≈ 2.97 → 2 pratas
Rank 3: k = (-1 + sqrt(1 + 32)) / 2 ≈ 2.37 → 2 pratas
Rank 4: k = (-1 + sqrt(1 + 24)) / 2 ≈ 1.99 → 2 pratas
Total = 4 + 2 + 2 + 2 = 10 >= 10. Yes!
result = 12, high = 11
mid = 11
Rank 1: 4 pratas (1+2+3+4=10 ≤ 11)
Rank 2: 2 pratas (2+4=6 ≤ 11)
Rank 3: 2 pratas (3+6=9 ≤ 11)
Rank 4: 1 prata (4 ≤ 11, but 4+8=12 > 11)
Total = 4 + 2 + 2 + 1 = 9 < 10. No!
low = 12
low > high, loop ends.
Result: 12
Verification:
Time 12:
Cook 1 (rank 1): 4 pratas in 1+2+3+4 = 10 min
Cook 2 (rank 2): 2 pratas in 2+4 = 6 min
Cook 3 (rank 3): 2 pratas in 3+6 = 9 min
Cook 4 (rank 4): 2 pratas in 4+8 = 12 min
Total = 10 pratas ✓
Complexity Analysis
- Time Complexity: O(L × log(maxTime))
- Binary search: O(log(maxTime)) iterations
- Each iteration: O(L) to calculate total pratas
- maxTime ≈ R_max × P × (P+1) / 2
- Space Complexity: O(L) - For ranks array
SPOJ Solution Template
Key Takeaways
- Binary Search on Answer: Search for minimum time where condition is satisfied
- Quadratic Time Formula: Time for k pratas = R × k(k+1)/2
- Inverse Formula: Use quadratic formula to find max pratas in given time
- Upper Bound: Worst cook making all pratas gives upper bound
- Parallel Execution: All cooks work simultaneously
- Monotonic Property: More time → More pratas (non-decreasing)
- Similar Problems: Koko Eating Bananas, Capacity to Ship, Minimum Speed to Arrive