SRM 679, D2, 250-Pointer (ListeningSongs)

James S. Plank

Tue Sep 13 22:54:52 EDT 2016
It's best to think about this problem in parts, solving each part before proceeding to the next part:

Part 1: An album doesn't have T songs

This case is illustrated in example 6, but it comes from the constraints -- durations1 and durations2 can contain between 1 and 100 elements, and T will be between 1 and 100. There is nothing in the constraints that says that durations1.size() or durations2.size() is ≥ T.

So test for this case first, and return -1 if either vector is too small. Test it on example six.


Part 2: You should to listen to the T shortest songs on each album

The best way to figure this out is to sort both vectors, and then sum up the first T durations in both vectors. If that number is too big, return -1. Otherwise, subtract the number from the total number of seconds (you'll have to multiply minutes by 60). That's the amount of time you have left after listening to T songs on each album.

Part 3: Of the remaining songs, listen to the shortest ones until you run out of time, or you run out of songs

To do this, create a third vector. I called mine "FD" for "final durations." Create this from the songs in the two vectors that are not in the first T songs of either vector.

Now sort FD, and run through it, seeing if you can listen to each song. Return if you can't listen to a song. If you finish FD, you're done -- you can listen to all of the songs!


In sum, this program tripped up a lot of topcoders, but if you split it into parts, and use the sort() method from the algorithms library, the solution is pretty straightforward.

My Solution.

Running time analysis

Let n be the size of the largest vector (durations1 or durations2).

Part 1 is clearly O(1).

Part 2 is clearly O(n log n), (because sorting a vector with n elements is O(n log n), and sorting two vectors with n elements is also O(n log n)).

Part 3 is O(m log m) where m is equal to 2(n-T). If we assume that n is larger than T, then m is O(n) (because 2(n-T) is linear in n). So, Part 3 is O(n log n). This means the overall running time is O(n log n).

As I mentioned in class, you can make Part 3 O(n) if you retain the two vectors from Part 2, start at the T-th element of each, and add up the shortest songs from each vector. Since there is not a second sorting step to this, it is O(n). When you learn merge sort in CS302, this is equivalent to the "merge" operation.