Note: This post was written hours after the test, but published after the testing window.
At school this past week I told my (nerdy) friends that I would be merely looking at this month’s USA Computing Olympiad (USACO) Bronze problems and attempting them if I knew how to do them.
That was half of the truth.
In the middle of the past week, I decided to participate in the USACO Bronze division for real. I knew, in my mind, that this weekend’s test was going to absolute mental battle. I knew it was going to be a very hard test. It was me against the dark voices in my mind saying, “You can’t do it” or “You’re not going anywhere”. It was me against my past self. The real me pushes on, works hard, and keeps going, despite a multitude of failures and setbacks along my computer science journey. The real me is willing to start from ground zero and do whatever it takes to get to my goals, my hopes, and my dreams.
One thing I’ve realized is to be open and honest with yourself. The better you know yourself (e.g “I tend to get combinatorics questions wrong”), the better chance you have at making yourself the best that you can be.
Today, I opened up my computer in the morning to find the USACO website down. I wasn’t expecting this and proceeded to do a Codeforces problem. After cooking and munching down breakfast, I promptly checked the website again and found it accessible. I then proceeded to use some time to attempt Moo Language, the notoriously hard Bronze problem that even some platinum participants couldn’t solve. After coding up the solution, I realized I had a small conceptual bug somewhere. This was where the skirmishes began. I had to push every inch of my mental perseverance and toughness to figure out exactly what was wrong. After toiling endlessly for an hour, I figured it out and made slight adjustments to my code. I submitted it, and voila.

I just solved the presumably hardest USACO bronze problem on the website.
After finishing lunch, I started the January contest. I decided to focus on the problems one by one instead of rushing to try to get ideas for all three, which I tried and failed terribly in December. I thought I had a good idea for the first problem until I realized I didn’t. I tweaked this bad idea into a better one by storing the indices of the same number in a vector of vectors and iterated through for each color, which ran in and is correct. You could prove so by considering adjacent indices of color: if they have a distance of at least 3, then a majority can’t agree. If the distance is 1 or 2, the majority is always able to agree. When two colors are exactly one or two apart, we can always make the whole array that number by repeatedly extending a subarray to one more its size.
After solving the simple greedy in about fifteen minutes, I read the second problem. I, having learned from last year’s December Bronze P1, immediately recognized it as a simulation. I carefully implemented it and got most of the test cases, except for the ones that timed out. As one of my coding friends had said earlier, it’s best to think about the “bad”, raw brute force or simulation solution and then think about what small optimizations you can make to reduce the time complexity of the algorithm. I thought about any cases where Bessie could jump for an infinite amount of time, and tried to resolve that difficulty. It turns out Bessie could jump for an infinite amount of time between two jump pads that only reverse the direction (i.e. the value is zero). Thus, I solved the complete problem by keeping track of whenever Bessie arrives at a “0-pad” at a particular position and with a particular direction and magnitude (VECTOR!), and checking whether two entries of these types are the same. I had to calm myself down a lot on this one especially because I wanted to get the full problem, not just partial credit.
I read the third problem. Upon reading it, I didn’t have a complete understanding of what to do. I drew out a few test cases in despair and made little to no progress. Despite the voices in my head trying to push me down, I pushed through. Deep down, I could solve this problem and auto-promote today. I eventually came up with an simulation algorithm that worked for the first ten test cases, just at least having a chance of a silver promotion (my score was about 888 at the time). But I wanted more.
I got stuck and took a break from the intense problem-solving for a while. I asked myself, What optimizations could I make? and Is there a better way to keep track of the prefixes? You thought of prefix sums before, didn’t you? I was reminded of the maximum subarray sum, which had a similar idea of keeping track of the best sum at every point in time. This bronze problem wasn’t like that, but the idea of keeping track of a sum seemed familiar. Additionally, the amount from the previous operations for a certain element seemed to “add” on itself, since an operation goes something like +1 +2 +3 +4 +5 if we have . I focused and debugged my code for a while and at last resolved the last five test cases by letting two separate sums be the negation of the first element, and iterating from
instead of
.
And I got it. With two hours left.

The celebration lasted for a moment. But more importantly, my prospects for computer science are clear. I have much more to do. I will proceed to take silver tomorrow.