diff --git a/posts/algorithms/cp-log.html b/posts/algorithms/cp-log.html index e905a1f..ad471c8 100644 --- a/posts/algorithms/cp-log.html +++ b/posts/algorithms/cp-log.html @@ -35,6 +35,311 @@

Competitive Programming Log

+

sorting and searching—24/2/2025

+

+ A lot of these problems I'd seen before but this is good + practice anyway. This really is a great problem set. After being + stuck on implementation details, I took less time banging my head + against the wall and just looked at the solution. +

+
+
    +
  1. + distinct numbers: unordered classes are exploitable and nearly always tle. Keep + it simple, use a map or PBDS. +
  2. +
  3. + apartments: distracted working on this during class but figured it out. + prove statements and use descriptive variable names. +
  4. +
  5. + ferris wheel: leetcode copy from people fitting in boats. Can't say + much because I already did it. +
  6. +
  7. + concert tickets: totally used PBDS, which is most likely way overkill. + if it works, it works. +
  8. +
  9. + restaurant customers: already seen it (line sweep) +
  10. +
  11. + movie festival: already seen it but + improve greedy/exchange arguments +
  12. +
  13. + missing coin sum: + I still don't get this. Write it out. +
  14. +
  15. + collecting numbers ii: I had the exactly correct idea but I thought it was too + complex. Practice will improve me developing my better sense of + this. Still, I didn't completely understand my idea, + which lowered my confidence. +
  16. +
+
+

more cses—22/2/2025

+
+
    +
  1. + gray code: Missed the pattern + gave up too late +
  2. +
  3. + towers of hanoi: Recursive grasp is limp—missed the idea. + Math/proof grasp too—still don't understand how its + \(2^n\). +
  4. +
  5. + apple division: I got distracted by the idea that it was NP-hard. Even when + Sam Altman told me it was DP, I failed to simplify it to "add + every element either to one or the other set". +
  6. +
  7. + digit queries: got the idea + time complexity quickly, but the + math-based implementation is weak. Jumped into the code + before outlining a strict plan. +
  8. +
+
+

cses—21/2/2025

+
+

+ Everyone recommends CSES so I started with it, doing the first 8 + problems. +

+
    +
  1. + weird algorithm: Trivial, but I forgot to print 1 at the end. + Return the exactly correct answer. +
  2. +
  3. + + missing number : N/A +
  4. +
  5. + + repetitions : Use invariants. +
  6. +
  7. + + increasing array : Run through one iteration of the algorithm. Here, I + erroneously added x - last to a quantity, + after manipulating x. +
  8. +
  9. + permutations: I'd seen this problem before yet struggled. + Fully understand the problem constraints. In this case, + While I understood the definition of a permissible permutation, + I didn't fully internalize that you could place number + wherever you want. Instead, I was locked in on placing + some x at i, i + 2, i + 4, .... + Further, the fact that I didn't immediately recognize this + solution means I need to improve at + upsolving and reviewing problems. +
  10. +
  11. + permutations: Absolutely disastrous. I continually just f*dged with the + offsets I was adding to my strategy until I happened to get the + answer right. Don't guess. Also, + don't be lazy—if an algorithm works, focus, write it + out, and enjoy being correct. +
  12. +
  13. + two knights: Required 2 hints from Sam Altman. + git gud at combinatorics. Use the paradigm "count good, + remove bad." Lock in less on counting specifics—instead, + consider what objects mean in aggregate. In this case, a + \(2\times3\) grid represents an "area" of attack, contributing 2 + bad knight pairs. This is much easier to digest then attempting + to remove overcounting per-knight. Fundamentally, the problem + involves placing 2 knights, so breaking it down 2 knights at a + time is the most intuitive take. +
  14. +
  15. + two sets: Don't lock in on one approach. Here, this is dp. The + fact that I knew the idea of partitioning the first \(n\) + numbers into two groups of size \(\frac{n(n+1)}{4}\) but failed + to recognize the greedy approach means I didn't grasp the + fundamental arithmetic of the problem, nor the greedy idea: + every number must go into a set. If you add the largest number + possible to set 1 to not exceed the target, this number can + always be formed in the other set by choosing \(1\) and \(x-1\). + git gud at greedy. +
  16. +
+
+

+ 938 (div. 3)—15/2/2025 +

+
+

+ What would've been my best contest. Unfortunately, CodeForces + decided to go down for TREE[3] centuries, which absolutely ruined + my groove in the contest and terminated my virtual. No excuses, + though, as I set a timer and finished up later. +

+

A

+

Brute-forced it but it still took me a few minutes.

+
    +
  1. Read (and exploit) problem constraints
  2. +
  3. + Go back and derive the linear optimization (choosing the one + with better marginal utility) +
  4. +
  5. If you have a (simple enough) solution, just go with it.
  6. +
+

B

+

+ Easily recognized how to form the matrix (i.e. smallest element + first with positive integers \(c,d\)) but tripped up on the + implementation. +

+
    +
  1. + Flesh out the steps before coding (i.e. walk through iterations + in head, transitions, edge cases on the rows and columns, i.e. + checking if i==n-1) especially on + implementation-heavy problems +
  2. +
+

C

+

+ Did a horrific (but correct) binary search solution. Tripped up by + specifics of std::{upper,lower}_bound regardless. + Technically, generating the prefix and postfix arrays takes two + passes and two binary searches to find the answer but this is + still more inefficient than the trivial linear scan. +

+
    +
  1. THE INT OVERFLOW INCIDENT
  2. +
  3. + Deepen understanding of binary search & STL functions to the + point that it is second nature +
  4. +
  5. Consider simple solutions first.
  6. +
+

D

+

+ Instantly recognized sliding window but struggled with minor + details (i.e. keeping track of match count) by rushing to the + solution. +

+
    +
  1. + Problem statement took a long time to grasp. Look at examples + and just read through slower (don't rush!) +
  2. +
  3. + Sliding window grasp isn't rigorous—improve this + later +
  4. +
  5. + When you don't remember 100% of how an algorithm works, + mentally walk through a few iterations +
  6. +
  7. Improve PBDS API familiarity (practice)
  8. +
+

E

+

+ I had mentally tapped out by this point (I submitted a TLE + \(O(n^2k)\) solution without using my brain). I solved F first, + then took a look at G before coming back to E, robbing me + of 10 minutes that could've been the difference between another + solve. +

+
    +
  1. + You're not like that. Solve problems in order (most of the time, + although skipping to F first was a wise decision). +
  2. +
  3. + Consider ideas fully before dropping them. I considered + the difference array, then discarded it, erroneously + believing a boolean was sufficient and completely forgetting + that the concept of ranges complicates flipping. +
  4. +
  5. + Formalize constraints more clearly to help form a solution. For + example, the idea that flipping things twice makes no + difference, permitting the use of a boolean difference array. +
  6. +
  7. + Prove correctness. I didn't prove that iterating left to right, + toggling a range of k actually would always give a correct + answer. +
  8. +
+

F

+

+ Had the solution quickly but overcomplicated the implementation. + Walked through the examples and took my time. +

+
    +
  1. + Failed to formalize the answer to the problem. I noticed + patterns but should've strictly defined the following rule: + "Every even count of a number contributes one to the score. + Further, one triple of 1, 2, 3 also contributes one." + Ultimately, I ended up submitting something I wasn't certain + would be correct. +
  2. +
+

G

+

+ Wasted time believing this was primitive DP, when it totally + wasn't. +

+
    +
  1. You're not that guy (yet >:))
  2. +
  3. + Prove optimal substructure and overlapping subproblems before + using DP & walk through the test cases. In this case, test case + 3 immediately disproves dp. +
  4. +
+

the beginning—12/2/2025

@@ -61,238 +366,6 @@ difficulty.

-

- 938 (div. 3)—15/2/2025 -

-

- What would've been my best contest. Unfortunately, CodeForces - decided to go down for TREE[3] centuries, which absolutely ruined my - groove in the contest and terminated my virtual. No excuses, though, - as I set a timer and finished up later. -

-

A

-

Brute-forced it but it still took me a few minutes.

- -

B

-

- Easily recognized how to form the matrix (i.e. smallest element - first with positive integers \(c,d\)) but tripped up on the - implementation. -

- -

C

-

- Did a horrific (but correct) binary search solution. Tripped up by - specifics of std::{upper,lower}_bound regardless. - Technically, generating the prefix and postfix arrays takes two - passes and two binary searches to find the answer but this is still - more inefficient than the trivial linear scan. -

- -

D

-

- Instantly recognized sliding window but struggled with minor details - (i.e. keeping track of match count) by rushing to the solution. -

- -

E

-

- I had mentally tapped out by this point (I submitted a TLE - \(O(n^2k)\) solution without using my brain). I solved F first, then - took a look at G before coming back to E, robbing me of 10 - minutes that could've been the difference between another solve. -

- -

F

-

- Had the solution quickly but overcomplicated the implementation. - Walked through the examples and took my time. -

- -

G

-

- Wasted time believing this was primitive DP, when it totally wasn't. -

- -

cses—21/2/2025

-

- Everyone recommends CSES so I started with it, doing the first 8 - problems. -

- -

more cses—22/2/2025

-