886 lines
40 KiB
HTML
886 lines
40 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<link rel="stylesheet" href="/styles/common.css" />
|
|
<link rel="stylesheet" href="/styles/post.css" />
|
|
<link rel="icon" type="image/webp" href="/public/logo.webp" />
|
|
<link href="/public/prism/prism.css" rel="stylesheet" />
|
|
<link href="/public/prism/prism-theme.css" rel="stylesheet" />
|
|
<script defer src="/public/prism/prism.js"></script>
|
|
<script
|
|
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
|
|
async
|
|
></script>
|
|
<title>Barrett Ruth</title>
|
|
</head>
|
|
<body class="graph-background">
|
|
<header>
|
|
<a
|
|
href="/"
|
|
style="text-decoration: none; color: inherit"
|
|
onclick="goHome(event)"
|
|
>
|
|
<div class="terminal-container">
|
|
<span class="terminal-prompt">barrett@ruth:~$ /algorithms</span>
|
|
<span class="terminal-cursor"></span>
|
|
</div>
|
|
</a>
|
|
</header>
|
|
<main class="main">
|
|
<div class="post-container">
|
|
<header class="post-header">
|
|
<h1 class="post-title">Competitive Programming Log</h1>
|
|
</header>
|
|
<article class="post-article">
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1873/" target="_blank"
|
|
>898 (div. 4)</a
|
|
>—3/4/2025
|
|
</h2>
|
|
<div>
|
|
Placed top 2000 but did not learn much. Was distracted (thinking
|
|
about writing this post itself) and was not taking the problems
|
|
seriously because they were not that challenging in the first place.
|
|
<blockquote>
|
|
Take problems seriously or you're wasting your time.
|
|
</blockquote>
|
|
. I was also continually nervous/pressuring myself and thought about
|
|
my own thought process. The time for analysis is after, not during.
|
|
<blockquote>Pressure ruins performance.</blockquote>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
A: couldn't come up with the extensible solution and checked all
|
|
permutations. Step back and use explicit criteria, i.e. "what
|
|
qualifies being able to make it in one swap?" (at most 2
|
|
characters being off).
|
|
</li>
|
|
<li>B: good math proof WLOG. Learning.</li>
|
|
<li>
|
|
Took a step back to architect the easiest way to count the score.
|
|
However,
|
|
<b
|
|
>only after erroneously calculating the score with an approach I
|
|
had already deemed incorrect</b
|
|
>.
|
|
</li>
|
|
<li>C: Trivial but should've been more patient.</li>
|
|
<li>D: binary search took me a second, but ok.</li>
|
|
<li>
|
|
E: sliding window but erroneously checked \(a[\{l,r-1\}] \%
|
|
a[\{l+1,r\}]\neq0\) <i>without</i> confirming it was in the
|
|
sliding window first. Err on the side of caution (i.e. if checks,
|
|
explicit edge cases, etc). Debugging could be
|
|
improved—target the likely differences between what you
|
|
<i>think</i> you're doing and what you're <i>actually</i> doing.
|
|
</li>
|
|
<li>
|
|
G: tried and didn't fully invest my time. For some reason my
|
|
subconscious still thinks getting lucky is a valid option.
|
|
</li>
|
|
<li>
|
|
H: <i>much</i> easier than G. Formulated the solution formally
|
|
before coding, allowing me to implicitly catch a lot of edge
|
|
cases: "whether V can get to the node closest to it in the graph's
|
|
cycle strictly before M."
|
|
</li>
|
|
</ul>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1892/" target="_blank"
|
|
>871 (div. 4)</a
|
|
>—28/3/2025
|
|
</h2>
|
|
<div>
|
|
Div. 4 to practice implemenation skills + mathematical observations
|
|
thanks to
|
|
<a
|
|
href="http://www.gang.umass.edu/~franz/Paul_Zeitz_The_Art_and_Craft_of_Problem_SolvingBookosorg.pdf"
|
|
target="_blank"
|
|
>Paul Zeitz</a
|
|
>. From now on, I will only note useful problems.
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
B: typo, costing a few minutes. Go slower. Declare variables.
|
|
Think consistently through approach.
|
|
</li>
|
|
<li>
|
|
C: paused an found a general implementation as Zeitz advises
|
|
(starting with a general, non-mathematical solution: "The solution
|
|
is the earliest to get either both 1s at once or each over two
|
|
strings"). <b>I still rushed</b>, incorrectly computing the result
|
|
as
|
|
<code>min(first, second)</code>
|
|
instead of
|
|
<code>first + second</code>.
|
|
</li>
|
|
<li>
|
|
D: I looked up the recurrence relation \(T(n)=T(n/3)+T(2n/3)\) to
|
|
ensure it was sub-linear time.
|
|
<blockquote style="font-style: italic">
|
|
Gain the mathematical skills to both analyze and derive (i.e. if
|
|
you forget) recurrence relations.
|
|
</blockquote>
|
|
</li>
|
|
<li>
|
|
E: spent <i>forever</i> fanagling with my Disjoint Set Union
|
|
template. I made countless errors including:
|
|
<ol>
|
|
<li>
|
|
Not inserting nodes into the data structure before joining
|
|
them
|
|
</li>
|
|
<li>
|
|
Joining zero/non-zero nodes, corrupting the component graph
|
|
</li>
|
|
<li>
|
|
Erroneously updating component sums by double counting (i.e.
|
|
using a mutated value).
|
|
</li>
|
|
</ol>
|
|
<blockquote>
|
|
Understand data structures before you use them. Despite what
|
|
Colin Galen says, black-boxed knowledge often isn't enough.
|
|
Improve knowledge of Fenwick Trees, Segment Trees, and Union
|
|
Find.
|
|
</blockquote>
|
|
</li>
|
|
<li>
|
|
F: elegant approach and reduction, eliminating the need for a
|
|
graph traversal.
|
|
</li>
|
|
<li>
|
|
G: <i>intentionally</i> chose the mathematical/indexing method to
|
|
improve my skills. I'd also like to use
|
|
<code>{upper,lower}_bound</code> more often with a lambda than
|
|
manually code binary search.
|
|
<b
|
|
>Once again, I practiced in a fundamentally flawed way, choosing
|
|
an approach I knew would be error prone and difficult</b
|
|
>.
|
|
<blockquote>
|
|
Don't be scared if you initilly can't find an easy
|
|
implementation.
|
|
<i>Reconceptualize, visualize, and reframe</i> until something
|
|
comes up. Sometimes, this takes too long—however, my
|
|
threshold for that realization is MUCH too low.
|
|
<b
|
|
>Spend a longer time developing/considering approaches even if
|
|
you already know a feasible solution</b
|
|
>. Here, I spent ~5 minutes developing a solution, then 20
|
|
minutes coding it. Instead, another 5 minute allocation of time
|
|
could lead me to the prefix sum solution, likely saving ~10
|
|
minutes.
|
|
</blockquote>
|
|
</li>
|
|
</ul>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1872/" target="_blank"
|
|
>895 (div. 3)</a
|
|
>—26/3/2025
|
|
</h2>
|
|
<div>
|
|
<p>Decent.</p>
|
|
<ul>
|
|
<li>
|
|
A: math intuition building. Jumped to assuming the problem
|
|
statement but it was much simpler.
|
|
<b>Answer the problem only.</b>
|
|
</li>
|
|
<li>
|
|
B: textbook simple problem that I struggle to mathematically
|
|
quantify being distracted by many components. In retrospect, I
|
|
should interpret the problem simply like:
|
|
<blockquote>
|
|
Each trap has a known time I must return by. The answer is
|
|
therefore the minimum of these.
|
|
</blockquote>
|
|
I also just plug in \(ceil\) and \(floor\) until I find the
|
|
right answer (I'm not lying). Instead, note that for
|
|
\(s,k\in\mathbb{Z}\),
|
|
\[\frac{s}{2}>k\leftrightarrow\lfloor\frac{s-1}{2}\rfloor\geq
|
|
k\]. This simply "edges out" the fractional term to line up
|
|
cleanly with the divisor.
|
|
</li>
|
|
<li>C: cooked. <b>Practice number theory.</b></li>
|
|
<li>
|
|
D: took me a while because I was distracted with the moving
|
|
parts. Specifically, I forgot that I could choose the
|
|
permutation and that the question was merely asking to pick the
|
|
largest/smallest numbers on \(x\)/\(y\) slots respectively. End
|
|
solution was expressive and elegant.
|
|
<b
|
|
>Express the question and reframe the constraints in simple
|
|
but accurate terms</b
|
|
>.
|
|
</li>
|
|
<li>
|
|
E: Black-boxed a lazy segment tree (with the help of AI, I must
|
|
admit—I need to make a template).
|
|
<blockquote>
|
|
<i
|
|
>Everything I did here was wrong and this problem showed an
|
|
embarrassingly fundamental flaw in my practice strategy.</i
|
|
>
|
|
</blockquote>
|
|
Namely, I should divide up practice time into:
|
|
<ol>
|
|
<li>Contests, emphasizing speed and implementation</li>
|
|
<li>
|
|
Single problems, emphasizing specific learning objectives
|
|
</li>
|
|
</ol>
|
|
</li>
|
|
In this problem, I immediately saw the application of the lazy
|
|
segment tree but decided to hold off on it, failing to find the
|
|
simpler prefix-XOR solution. Therefore, I not only wasted my time,
|
|
but also cemented in unrealistic practice (I would never do this
|
|
in a real contest) and worsened my virtual contest performance. As
|
|
for the prefix-XOR solution, focusing on just one/zero
|
|
corresponding elements and
|
|
<b>walking through small examples</b>
|
|
(i.e. "what happens when \(l=r\)?") would've help me pick up the
|
|
pattern.
|
|
</ul>
|
|
</div>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/2091" target="_blank"
|
|
>1013 (div. 3)</a
|
|
>—25/3/2025
|
|
</h2>
|
|
<div>
|
|
<p>
|
|
Solved in a coffee shop. More locked in than before. My best
|
|
performance yet. I'm changing my philosophy in these
|
|
contests—I want to be able to code nearly everything (except
|
|
for, for example, a lazy-propagation segment tree) from scratch.
|
|
These contests should test my ability to <i>code</i> and I mean
|
|
the whole package. Lastly, my skills in math and implementation
|
|
are improving bit by bit. No stopping here.
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
A: rushed and panicke for no reason. Took me a few minutes to
|
|
realize the triviality of the solution. <b>Calm down!</b>
|
|
</li>
|
|
<li>
|
|
B: failed to prove solution before testing, resulting in a time
|
|
waste of around 10 minutes. Collected myself and proved it,
|
|
though
|
|
<b>rigor could be improved</b>.
|
|
</li>
|
|
<li>
|
|
C: noticed a pattern in the examples after rotating them and
|
|
instantly submitted. <b>Risky decision!</b> The problem is, I'm
|
|
unsure if I am even capable of proving the validity of the
|
|
solution in the first place.
|
|
</li>
|
|
<li>
|
|
D: afk for ~45 minutes but still heavily struggled with the
|
|
solution, <i>even after reducing the problem</i> to maximally
|
|
spreading out \(\lceil{\frac{k}{n}}\rceil\) columns. Recollected
|
|
myself and came up with a solution that worked for me in
|
|
minutes.
|
|
</li>
|
|
<li>
|
|
E: played with the numbers and realized the prime reduction.
|
|
<b>Number theory very weak</b>—this is most likely the
|
|
hardest problem in the category I've ever solved. Still had to
|
|
google sieve of eratosthenes (is this cheating?) (<b
|
|
>contest as a test of implementation skills</b
|
|
>).
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1878/" target="_blank"
|
|
>900 (div. 3)</a
|
|
>—22/3/2025
|
|
</h2>
|
|
<div>
|
|
<p>
|
|
Solved in a coffee shop. Used AI for smaller things (otherwise I'd
|
|
have no idea).
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
A: Solved a much harder problem related to majority element
|
|
paths on tree—realized the solution after a minute.
|
|
</li>
|
|
<li>
|
|
B: was confused for about 7 minutes but realized some properties
|
|
of divisibility and odd numbers.
|
|
<b
|
|
>Math is still a weakness. Take simpler approaches to complex
|
|
constraints, such as considering parity.</b
|
|
>
|
|
</li>
|
|
<li>
|
|
Went off of gut instinct that it is always possible to form the
|
|
given \(x\) if encompassed in the range of numbers.
|
|
<b
|
|
>Failed to prove this mathematical validity but had fair
|
|
intuition</b
|
|
>
|
|
(i.e. just "take off one" if too big/small). This is acceptable,
|
|
though not perfect.
|
|
</li>
|
|
<li>
|
|
D: cooked. Solved E first and had mentally given up by this
|
|
point.
|
|
<b
|
|
>If you've given up, just stop trying and take a break/do
|
|
something else. You're wasting your time.</b
|
|
>
|
|
</li>
|
|
<li>
|
|
E: incredibly easy with segtree. Realized the lower bound/walk
|
|
solution after 2-3 minutes. Binary search indexing can be
|
|
improved (i.e. which pointer to return?) as well as realizing
|
|
one binary search is necessary across both arrays. Good
|
|
mathematical deduction to realize relationship between input
|
|
arrays. Revisit sparse table + simpler solution—<i
|
|
>don't be content with an advanced solution when a
|
|
simpler/elegant idea also suffices</i
|
|
>.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1857/" target="_blank"
|
|
>891 (div. 3)</a
|
|
>—{6,7}/5/2025
|
|
</h2>
|
|
<div>
|
|
<p>
|
|
Solved partially on the plane and at home. Best round in terms of
|
|
acceptance rate. After bombing another codeforces contest & more
|
|
CSES work, it's clear that my biggest weakness is
|
|
<b>algorithmic correctness and certainty</b>. To remedy:
|
|
</p>
|
|
<ul>
|
|
<li>Test edge cases (boundary + tricky)</li>
|
|
<li>Don't submit unless you're <i>certain</i> you're right</li>
|
|
<li>In analysis, leave no stone unturned (be thorough)</li>
|
|
<li>
|
|
Don't rely on the given test cases as proof of correctness.
|
|
</li>
|
|
</ul>
|
|
<ol>
|
|
<li>
|
|
A: ironically, although I got AC in ~1 minute, this is exactly
|
|
where I go wrong. I did not check the actual correctness of my
|
|
parity checks but submitted anyway.
|
|
</li>
|
|
<li>
|
|
B: AC once again but <b>implementation is still a weakness</b>.
|
|
In this case, it was due to a lack of problem understanding,
|
|
i.e. rounding up sets all right digits to 0, but carries can
|
|
still affect the number after that.
|
|
</li>
|
|
<li>
|
|
C: skipped and came back later. The idea of sorting came up but
|
|
I was overwhelmed. My end solution was a bit overcomplicated but
|
|
still logically sound. I'm getting better at making
|
|
observations, in this case explicitly identifying the fact that
|
|
the largest element must have one more element greater than or
|
|
equal to itself, permitting you to build the answer in reverse
|
|
order. <b>Did not prove the correctness of this</b>.
|
|
</li>
|
|
<li>
|
|
D: skipped and came back later. Given the large amount of
|
|
vertices I did a good job of rephrasing the data (thanks
|
|
<a
|
|
href="https://www.google.com/search?q=how+to+solve+it"
|
|
target="_blank"
|
|
>George Pólya</a
|
|
>) and <b>proving</b> the correctness with
|
|
transitivity/contradiction. Initial solution
|
|
complex—ponder implementation before going at it.
|
|
</li>
|
|
<li>
|
|
E: took me a while (I believe) because I was on a plane without
|
|
a notebook and visualizing was hard. Good mathematical
|
|
formulation, but initially returned the answer in wrong order.
|
|
<b
|
|
>Relied on the test cases to save me—ensure you're
|
|
solving the actual problem</b
|
|
>
|
|
(in this case, returning the queries in the right order).
|
|
</li>
|
|
<li>
|
|
F: Quadratic equation flew over my head. I was unsure but
|
|
should've just played with the numbers—if you plug them
|
|
in, you derive the quadratic equation relevant to the problem. I
|
|
then (maybe) could've gotten an answer. Instead, I was
|
|
intimidated because I thought I needed some fancy
|
|
DSA/dp/two-pointers/two-sum thing. Just have to build more
|
|
intuition. Also, totally did not know how to count number of
|
|
distinct pairs \(i, j\) with \(i\lt j\) for two elements. I
|
|
missed the case when the elements are equal and, yes, seriously
|
|
forgot it is just the product (I do not want to talk about it
|
|
but thanks Deepseek).
|
|
<b>Overflow, again. rly dude?</b>
|
|
</li>
|
|
<li>
|
|
F: doing this later, got the core insight of the minimal weight
|
|
edge path. Once again, for surveying path
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>cses (range queries, sorting and searching)—1/3/2025</h2>
|
|
<div>
|
|
<p>
|
|
A good review and challenge of data strucures. I've become even
|
|
more of a fan of CSES. On codeforces, the application of fenwick
|
|
trees and segment trees are usually on problems out of my reach,
|
|
where I'm battling both the problem and the data structures.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
static range minimum queries: sparse table. copy-pasted from
|
|
template, should be able to derive
|
|
</li>
|
|
<li>
|
|
range update queries: fenwick tree difference array.
|
|
<b
|
|
>understanding of fenwick trees fundamentally flawed. "guessed
|
|
and checked" on the ranges to update.</b
|
|
>
|
|
</li>
|
|
<li>
|
|
forest queries: inclusion-exclusion principles.
|
|
<b>think before implement.</b>
|
|
</li>
|
|
<li>
|
|
hotel queries: fun question, derived segment tree
|
|
<code>{lower,upper}_bound</code> (a "walk", apparently).
|
|
</li>
|
|
<li>
|
|
list removals: overcomplicated it a lot. Note that an index can
|
|
be interpreted as a relative position into an array, so an
|
|
indexed set works perfectly fine.
|
|
<b>Reinterpret problem constraints.</b>
|
|
<b>Extreme lack of familiarity with PBDS/STL APIs</b>. I
|
|
constantly confuse <code>find_by_order</code>,
|
|
<code>order_of_key</code>, <code>erase(*it)</code> vs.
|
|
<code>erase(it)</code>.
|
|
</li>
|
|
<li>
|
|
traffic lights: destroyed. I'm at the point where I thought "oh,
|
|
there's no way I'd need two data structures. Too complicated,
|
|
let me see the solution."
|
|
<b
|
|
>Trust your intuition a bit more, especially if you know your
|
|
solution will lead to a right answer</b
|
|
>. The offline solution also fully went over my head, in which
|
|
answering queries backwards presents a 4x (performance-wise)
|
|
faster solution.
|
|
<b
|
|
>Answer the question—you can do so by any means
|
|
necessary</b
|
|
>. In this case, reinterpreting the key insight that adding a
|
|
traffic like can only shrink intervals to removing a traffic
|
|
light can only increase them isn't only enough. I knew handling
|
|
the first case simply was too hard but I needed to
|
|
<b>dig deeper into ideas</b>. In this case, asking "ok, well is
|
|
it easier to answer the queries in reverse order? Well, yes,
|
|
because removing the <code>i</code>th light can either create a
|
|
larger gap around it, which I can easily find, or its the same
|
|
gap as before" would've saved me.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/2072" target="_blank"
|
|
>1006 (div. 3)—25/2/2025</a
|
|
>
|
|
</h2>
|
|
<div>
|
|
<ol>
|
|
<li>A: easy, messed up on the math a bit for a second</li>
|
|
<li>
|
|
B: for the second contest in a row, missed a B and solved E or
|
|
later. Solved ~2 min after the contest ended.
|
|
<b>Prove mathematical correctness.</b> Here, I did not and still
|
|
don't fully understand why a configuration like:
|
|
“hyphens...underscores...hyphens>” is even
|
|
optimal...
|
|
<b
|
|
>Still, I was mad that I couldn't get it and submitted
|
|
solutions that I had nowhere near certainty of their
|
|
correctness. If you aren't sure, you're better off
|
|
skipping it</b
|
|
>. Fortunately, in this case, maximizing your codeforces ranking
|
|
also coincides wiht optimal problem-solving: don't guess.
|
|
</li>
|
|
<li>
|
|
C: knew a solution almost instantly but got held up nearly 30
|
|
minutes on small implementation details and edge cases. Ended up
|
|
submitted something I wasn't certain was correct. Taking an
|
|
explicit extra minute to consider: “what do I print for
|
|
the last case? I must maximize the MEX and ensure the bitwise OR
|
|
equals x. If the MEX hits x, then print it. Otherwise, print
|
|
x” would've saved me upwards of 10 minutes.
|
|
</li>
|
|
<li>
|
|
E: masterclass in throwing. I knew the algorithm pretty much
|
|
immediately (manhattan distances and euclidean distances must be
|
|
equals means at least one coordinate must be the same between
|
|
each point). I then broke it down into building pairs
|
|
column-wise, the correct approach. Then, I simply
|
|
<b
|
|
>forgot to check a core constraint of the problem: place
|
|
\(\leq500\) staffs</b
|
|
>. I decided to brute force the last pairs rather than repeat
|
|
the strategy, which actually runs in logarithmic time (I also
|
|
didn't prove this). The final product was elegant, at
|
|
least.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>sorting and searching—24/2/2025</h2>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<div>
|
|
<ol>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1621" target="_blank"
|
|
>distinct numbers</a
|
|
>: unordered classes are exploitable and nearly always tle. Keep
|
|
it simple, use a map or PBDS.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1084" target="_blank"
|
|
>apartments</a
|
|
>: distracted working on this during class but figured it out.
|
|
<b>prove statements and use descriptive variable names.</b>
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1090" target="_blank"
|
|
>ferris wheel</a
|
|
>: leetcode copy from people fitting in boats. Can't say
|
|
much because I already did it.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1091" target="_blank"
|
|
>concert tickets</a
|
|
>: totally used PBDS, which is most likely way overkill.
|
|
<b>if it works, it works</b>.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1619" target="_blank"
|
|
>restaurant customers</a
|
|
>: already seen it (line sweep)
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1629" target="_blank"
|
|
>movie festival</a
|
|
>: already seen it but
|
|
<b>improve greedy/exchange arguments</b>
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/2216" target="_blank"
|
|
>missing coin sum</a
|
|
>:
|
|
<b>I still don't get this. Write it out.</b>
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/2217" target="_blank"
|
|
>collecting numbers ii</a
|
|
>: 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 <i>completely</i> understand my idea,
|
|
which lowered my confidence.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>more cses—22/2/2025</h2>
|
|
<div>
|
|
<ol>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/2205" target="_blank"
|
|
>gray code</a
|
|
>: Missed the pattern + <b>gave up too <i>late</i></b>
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/2165" target="_blank"
|
|
>towers of hanoi</a
|
|
>: <b>Recursive grasp is limp</b>—missed the idea.
|
|
<b>Math/proof grasp too</b>—still don't understand how its
|
|
\(2^n\).
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1623" target="_blank"
|
|
>apple division</a
|
|
>: 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".
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/2431">digit queries</a
|
|
>: got the idea + time complexity quickly, but the
|
|
<b>math-based implementation is weak</b>. Jumped into the code
|
|
<i>before</i> outlining a strict plan.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>cses—21/2/2025</h2>
|
|
<div>
|
|
<p>
|
|
Everyone recommends CSES so I started with it, doing the first 8
|
|
problems.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1068" target="_blank"
|
|
>weird algorithm</a
|
|
>: Trivial, but I forgot to print 1 at the end.
|
|
<b>Return the exactly correct answer.</b>
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1083" target="_blank">
|
|
missing number </a
|
|
>: N/A
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1069" target="_blank">
|
|
repetitions </a
|
|
>: Use invariants.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1094" target="_blank">
|
|
increasing array </a
|
|
>: Run through one iteration of the algorithm. Here, I
|
|
erroneously added <code>x - last</code> to a quantity,
|
|
<i>after manipulating <code>x</code></i
|
|
>.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1070/" target="_blank"
|
|
>permutations</a
|
|
>: I'd seen this problem before yet struggled.
|
|
<b>Fully understand the problem constraints</b>. In this case,
|
|
While I understood the definition of a permissible permutation,
|
|
I didn't fully internalize that you could place number
|
|
<i>wherever</i> you want. Instead, I was locked in on placing
|
|
some <code>x</code> at <code>i, i + 2, i + 4, ...</code>.
|
|
Further, the fact that I didn't immediately recognize this
|
|
solution means I need to improve at
|
|
<b>upsolving and reviewing problems</b>.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1071" target="_blank"
|
|
>permutations</a
|
|
>: Absolutely disastrous. I continually just f*dged with the
|
|
offsets I was adding to my strategy until I happened to get the
|
|
answer right. <b>Don't guess</b>. Also,
|
|
<b
|
|
>don't be lazy—if an algorithm works, focus, write it
|
|
out, and enjoy being correct</b
|
|
>.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1072" target="_blank"
|
|
>two knights</a
|
|
>: Required 2 hints from Sam Altman.
|
|
<b>git gud at combinatorics</b>. Use the paradigm "count good,
|
|
remove bad." Lock in less on counting specifics—instead,
|
|
consider what objects <i>mean in aggregate</i>. 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.
|
|
</li>
|
|
<li>
|
|
<a href="https://cses.fi/problemset/task/1092" target="_blank"
|
|
>two sets</a
|
|
>: <b>Don't lock in on one approach</b>. 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\).
|
|
<b>git gud at greedy</b>.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>
|
|
<a href="https://codeforces.com/contest/1955" target="_blank"
|
|
>938 (div. 3)</a
|
|
>—15/2/2025
|
|
</h2>
|
|
<div>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<h3>A</h3>
|
|
<p>Brute-forced it but it still took me a few minutes.</p>
|
|
<ol>
|
|
<li>Read (and exploit) problem constraints</li>
|
|
<li>
|
|
Go back and derive the linear optimization (choosing the one
|
|
with better marginal utility)
|
|
</li>
|
|
<li>If you have a (simple enough) solution, just go with it.</li>
|
|
</ol>
|
|
<h3>B</h3>
|
|
<p>
|
|
Easily recognized how to form the matrix (i.e. smallest element
|
|
first with positive integers \(c,d\)) but tripped up on the
|
|
implementation.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
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 <code>i==n-1</code>) <i>especially</i> on
|
|
implementation-heavy problems
|
|
</li>
|
|
</ol>
|
|
<h3>C</h3>
|
|
<p>
|
|
Did a horrific (but correct) binary search solution. Tripped up by
|
|
specifics of <code>std::{upper,lower}_bound</code> 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.
|
|
</p>
|
|
<ol>
|
|
<li>THE INT OVERFLOW INCIDENT</li>
|
|
<li>
|
|
Deepen understanding of binary search & STL functions to the
|
|
point that it is second nature
|
|
</li>
|
|
<li>Consider simple solutions first.</li>
|
|
</ol>
|
|
<h3>D</h3>
|
|
<p>
|
|
Instantly recognized sliding window but struggled with minor
|
|
details (i.e. keeping track of match count) by rushing to the
|
|
solution.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
Problem statement took a long time to grasp. Look at examples
|
|
and just read through slower (don't rush!)
|
|
</li>
|
|
<li>
|
|
Sliding window grasp isn't <i>rigorous</i>—improve this
|
|
later
|
|
</li>
|
|
<li>
|
|
When you don't remember 100% of how an algorithm works,
|
|
<b>mentally walk through a few iterations</b>
|
|
</li>
|
|
<li>Improve PBDS API familiarity (practice)</li>
|
|
</ol>
|
|
<h3>E</h3>
|
|
<p>
|
|
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 <i>before</i> coming back to E, robbing me
|
|
of 10 minutes that could've been the difference between another
|
|
solve.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
You're not like that. Solve problems in order (most of the time,
|
|
although skipping to F first was a wise decision).
|
|
</li>
|
|
<li>
|
|
Consider ideas <i>fully</i> before dropping them. I considered
|
|
the difference array, then <i>discarded</i> it, erroneously
|
|
believing a boolean was sufficient and completely forgetting
|
|
that the concept of ranges complicates flipping.
|
|
</li>
|
|
<li>
|
|
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.
|
|
</li>
|
|
<li>
|
|
Didn't get it, still don't get it, don't know why. Way easier
|
|
than D.
|
|
</li>
|
|
<li>
|
|
Prove correctness. I didn't prove that iterating left to right,
|
|
toggling a range of k actually would always give a correct
|
|
answer.
|
|
</li>
|
|
</ol>
|
|
<h3>F</h3>
|
|
<p>
|
|
Had the solution quickly but overcomplicated the implementation.
|
|
Walked through the examples and took my time.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
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.
|
|
</li>
|
|
</ol>
|
|
<h3>G</h3>
|
|
<p>
|
|
Wasted time believing this was primitive DP, when it totally
|
|
wasn't.
|
|
</p>
|
|
<ol>
|
|
<li>You're not that guy (yet >:))</li>
|
|
<li>
|
|
Prove optimal substructure and overlapping subproblems before
|
|
using DP & walk through the test cases. In this case, test case
|
|
3 immediately disproves dp.
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
<h2>the beginning—12/2/2025</h2>
|
|
<div>
|
|
<p>
|
|
This marks the (true) beginning of my competitive programming
|
|
journey. By "true" I mean intentional, focused, daily practice.
|
|
Driven by my admiration for competitive programmers, love of
|
|
challenge, and desire for a decent new-grad job, I'm excited to
|
|
start putting in the work.
|
|
</p>
|
|
<p>
|
|
This webpage will be an archive of everything related to this
|
|
process, including my practice strategies, setup, shortcomings,
|
|
logs, and more. For now, I'll be practicing on
|
|
<a href="https://codeforces.com" target="_blank">CodeForces</a>
|
|
(account
|
|
<a href="https://codeforces.com/profile/sigill" target="_blank"
|
|
>sigill</a
|
|
>) and <a href="https://cses.fi" target="_blank">CSES</a>, using
|
|
the
|
|
<a href="https://cses.fi/book/book.pdf" target="_blank"
|
|
>CP Handbook</a
|
|
>
|
|
and browsing by related problem tags with ever-increasing
|
|
difficulty.
|
|
</p>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</main>
|
|
<script src="/scripts/common.js"></script>
|
|
<script src="/scripts/post.js"></script>
|
|
</body>
|
|
</html>
|