This commentary is meant to give a brief outline of what is required to solve each problem and what challenges may be involved. It can be used to guide anyone interested in trying to solve these problems, but is not intended to describe all the details of a correct solution. We encourage everyone to try and implement these details on their own using their programming language of choice.
Attempts to solve past problems can be submitted on the CCC Online Grader. Also, after a contest is complete, official test data is available by clicking the corresponding “Download” button on our Past Contests webpage.
The first problem is designed to be accessible with some insight required to obtain full marks.
The first subtask can be hard-coded. That is, the following table can be calculated by hand and a solution can mimic looking up the correct output in the table.
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
Output | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 |
For the second and third subtasks, we can notice that we need
For a full solution, we can loop through only all possible values of
There is also a clever extremely quick solution that involves
extending the table listed above for the first subtask to
The second problem in this year’s competition requires input to be stored together in a data structure. Because the assignment of students to groups is not given until the end of the input, the constraints cannot be fully considered as they are encountered, and so must be stored in memory. It is helpful to also store the student groups in memory.
Once both types of input are in memory, a solution can be obtained by considering each constraint individually and maintaining a count of how many are violated.
Likely pitfalls include incorrectly assuming something about the order in which student names appear, and erroneously thinking that a group can only violate one constraint.
Care must be taken with the Boolean logic required to test if a given
constraint is violated. This will require determining if a given student
is in a given group. Doing this inefficiently by looping through all the
groups or looping through all the students should have allowed a
submission to earn 14 of the available 15 marks. To earn the final mark,
this look-up must be made more efficient. This can be accomplished using
a data structure built-in to the language designed for this very purpose
(e.g. a dictionary in Python, a HashMap
in
Java, or an unordered_map
in C++).
For the first subtask, it suffices to run a brute-force check of all possible outputs to determine if there is a piece that will satisfy the clarinet players.
For the second subtask, note that no sequence of length 3 is good.
Also, all sequences of length 1 are good. Thus, we should try to find a
piece with
For the third subtask, we can build on our solution to the second
subtask. As before, suppose we are building a piece, our current
sequence is
The last subtask involves the same idea but when adding a new number to the end, we have to instead do a proper check to see if the new number is too large.
For the first subtask, it suffices to follow the definition of a good
triplet. Firstly, there are P[b]-P[a] < (C+1)/2
in C++ or Java, or
P[b]-P[a] < (C+1)//2
in Python 3.
For the second subtask, the goal is to find a solution that works
well when
It is possible to optimize this approach to
In the first subtask, the students and their friendships form a line.
One approach to this subtask involves dynamic programming. Let
For each value of Y
, then it’s possible to perform this
transition by choosing a Y
student and
“expanding their influence” to all others, updating
For each
To solve the remaining subtasks, we’ll use a different dynamic programming formulation, this time on the tree structure formed by the students and their friendships. We’ll consider the tree to be rooted at an arbitrary node (student), such as node 1.
Let
if
if
if
Our answer will then be
As is typical for DP on trees, we’ll recurse through the tree, and
for each node i, we’ll compute
An implementation of this algorithm may take