Comprehensive Solutions for AtCoder ABC 065

<div> <h3>Problem 1: Freshness Assessment</h3> <p><b>Objective:</b> Determine the condition of food consumed after a delay.</p> <p>You possess an item with <i>A</i> days of remaining shelf life. You intend to consume it after <i>B</i> days. Consuming food that is already expired does not cause illness unless the time past the expiration date exceeds a threshold <i>X</i>. If the food is fresh, it tastes good. If it is expired but within the tolerance range <i>X</i>, it is safe. Beyond that, it poses a health risk.</p> <p><b>Methodology:</b> Calculate the number of days passed relative to the expiration date. If <i>A &minus; B &ge; 0</i>, the food has not expired yet. Otherwise, determine the extent of expiration. If the duration past expiration <i>(B &minus; A)</i> is less than or equal to <i>X</i>, the result is acceptable. Any excess results in a critical status.</p> <p><b>Implementation:</b></p> <pre><code>int main() { int limitDays, currentDaysLeft, waitTime; std::cin &gt;&gt; limitDays &gt;&gt; currentDaysLeft &gt;&gt; waitTime; int diff = currentDaysLeft - waitTime; if (diff &gt;= 0) { std::cout &lt;&lt; "delicious" &lt;&lt; std::endl; } else { int exceeded = waitTime - currentDaysLeft; if (exceeded &lt;= limitDays) { std::cout &lt;&lt; "safe" &lt;&lt; std::endl; } else { std::cout &lt;&lt; "dangerous" &lt;&lt; std::endl; } } return 0; }</code></pre> <hr> <h3>Problem 2: Lamp Control Sequence</h3> <p><b>Objective:</b> Navigate a directed graph representing lamp switches to reach a target state with minimum operations.</p> <p>There are <i>N</i> lamps numbered 1 through <i>N</i>. Initially, lamp 1 is active. Pressing the switch on lamp <i>i</i> toggles it off and activates lamp <i>a[i]</i>. Determine the minimum presses to activate lamp 2, or return -1 if impossible.</p> <p><b>Methodology:</b> This forms a functional graph where each node has exactly one outgoing edge. Starting from node 1, we trace the path. Since the graph size is finite, the path must eventually enter a cycle. If node 2 appears in the trajectory from node 1, record the steps. If node 2 is not found before entering a previously visited node, it is unreachable.</p> <p><b>Implementation:</b></p> <pre><code>void solve() { int numLamps; std::cin &gt;&gt; numLamps; std::vector&lt;int&gt; nextState(numLamps + 1); for(int i = 1; i &lt;= numLamps; ++i) { std::cin &gt;&gt; nextState[i]; } std::vector&lt;bool&gt; visited(numLamps + 1, false); int curr = 1; int steps = 0; // Traverse until target found or cycle detected while(!visited[curr]) { visited[curr] = true; curr = nextState[curr]; steps++; if(curr == 2) { std::cout &lt;&lt; steps - 1 &lt;&lt; "\n"; return; } } // Target not reached before loop closure std::cout &lt;&lt; "-1" &lt;&lt; "\n"; } </code></pre> <hr> <h3>Problem 3: Animal Arrangements</h3> <p><b>Objective:</b> Count the number of ways to arrange <i>N</i> dogs and <i>M</i> cats in a line such that no two animals of the same species stand adjacent.</p> <p><b>Methodology:</b> Valid arrangements require alternating types. This implies the absolute difference between the counts <i>|N - M|</i> cannot exceed 1. If the difference is greater than 1, the answer is 0. If <i>N == M</i>, the pattern can start with either a dog or a cat (2 choices), multiplied by the permutations of individual dogs and cats (<i>N! &times; M!</i>). If <i>|N - M| == 1</i>, the species with the higher count must start and end, leaving only 1 pattern configuration for species order, multiplied by internal permutations.</p> <p>Since results can be large, compute modulo <i>1E9 + 7</i>.</p> <p><b>Implemantation:</b></p> <pre><code>const int MOD_VAL = 1e9 + 7; long long factorial[100005]; void precompute() { factorial[0] = 1; for (int i = 1; i &lt;= 100000; i++) { factorial[i] = (factorial[i - 1] * i) % MOD_VAL; } } void solve() { precompute(); int n, m; std::cin &gt;&gt; n &gt;&gt; m; if (std::abs(n - m) &gt; 1) { std::cout &lt;&lt; 0 &lt;&lt; "\n"; return; } long long result = (factorial[n] * factorial[m]) % MOD_VAL; if (n == m) { result = (result * 2) % MOD_VAL; } std::cout &lt;&lt; result &lt;&lt; "\n"; } </code></pre> <hr> <h3>Problem 4: Connect Townships</h3> <p><b>Objective:</b> Find the minimum cost to connect all towns given their 2D coordinates. The cost between town <i>i</i> and <i>j</i> is <i>min(|xi - xj|, |yi - yj|)</i>.</p> <p><b>Methodology:</b> This is a Minimum Spanning Tree (MST) problem. Calculating all possible edges yields <math>O(N^2)</math> edges, which is too slow for <i>N = 10^5</i>. Observation dictates that for any dimension (X or Y), optimal edges exist only between geometrically adjacent points when sorted by that coordinate. Therefore, we sort the points by X, add edges between neighbors, repeat for Y, resulting in roughly <math>4N</math> candidate edges. Runing Kruskal's algorithm on this reduced set provides the solution efficiently.</p> <p><b>Implementation:</b></p> <pre><code>struct Point { int x, y, id; }; struct Connection { int u, v, w; bool operator&lt;(Connection const&gt; other) const { return w &lt; other.w; } }; struct DSU { std::vector&lt;int&gt; parent; DSU(int n) { parent.resize(n + 1); std::iota(parent.begin(), parent.end(), 0); } int find(int i) { if (parent[i] == i) return i; return parent[i] = find(parent[i]); } void unite(int i, int j) { int rootI = find(i); int rootJ = find(j); if (rootI != rootJ) parent[rootI] = rootJ; } }; void solve() { int N; std::cin &gt;&gt; N; std::vector&lt;Point&gt; cities(N); for (int i = 0; i &lt; N; i++) { std::cin &gt;&gt; cities[i].x &gt;&gt; cities[i].y; cities[i].id = i; } std::vector&lt;Connection&gt; potentialEdges; auto sortAndAdd = [&](int axisIdx) { std::sort(cities.begin(), cities.end(), [axisIdx](Point const&gt; a, Point const&gt; b) { return (axisIdx == 0) ? a.x &lt; b.x : a.y &lt; b.y; }); for (int i = 1; i &lt; N; i++) { Connection edge; edge.u = cities[i-1].id; edge.v = cities[i].id; edge.w = (axisIdx == 0) ? (cities[i].x - cities[i-1].x) : (cities[i].y - cities[i-1].y); potentialEdges.push_back(edge); } }; sortAndAdd(0); sortAndAdd(1); std::sort(potentialEdges.begin(), potentialEdges.end()); DSU dsu(N); long long totalCost = 0; int edgesCount = 0; for (const auto&amp; edge : potentialEdges) { if (dsu.find(edge.u) != dsu.finnd(edge.v)) { dsu.unite(edge.u, edge.v); totalCost = (totalCost + edge.w) % 1000000007; edgesCount++; if (edgesCount == N - 1) break; } } std::cout &lt;&lt; totalCost &lt;&lt; "\n"; } </code></pre> </div>

Tags: AtCoder Competitive Programming Beginner Contest C++ Problem Solving

Posted on Thu, 07 May 2026 07:56:10 +0000 by phpvn.org