Common Board| Show all threads Hide all threads Show all messages Hide all messages | | Calculate speed | yaustal | 1820. Ural Steaks | 7 Sep 2026 18:27 | 1 | #include <iostream> #include <cmath> int main() { int n, k; std::cin >> n >> k; if (n < k) { std::cout << 2; } else { double speed = 0.5 * k; int result = static_cast<int>(std::ceil(n / speed)); std::cout << result; } } | | Problem 1732. Ministry of Truth rejudged | Rejudge Bot | 1732. Ministry of Truth | 7 Sep 2026 04:36 | 1 | The following changes have been made to the problem: - new tests added - time limit adjusted All solutions have been rejudged. The number of authors affected: - 157 (18%) authors lost Accepted status - 8 (0.93%) authors gained Accepted status | | To admins: New tests | Milanin | 1589. Sokoban | 30 Aug 2026 22:27 | 5 | Hey admins, I've sent a couple of tests to timus_support@acm.timus.ru that my AC solution was struggling with. Please validate if they can be added to the system. Your tests have been added. Thanks! Milanin, thanks a lot for new tests! Now I've got AC only with neural networks solution. All solutions with just "optimizations"/"bad subfields & patterns", etc. didn't allow me to pass new tests. This is impressive. I still can't believe that there's a problem on Timus that has a meaningful neural network based solution. Finally, 0.062 sec without neural networks. Just correct removing of "bad" fields, effective hash/pq implementations + bit tricks & memory optimizations + A*. I have been working on this problem since it appeared - the 2007 student quarterfinal, I went there with a team from SUrSU. Later I tried many different approaches and in practice, the hardest tests in this problem are those with 12 and 13 boxes. In the end, the solution turned out as follows: 1. Use uint64_t bit masks to store the board state (36 bits for the box positions + the coordinates of the upper-left corner of the connected component in which Stas is located) + 22 bits remain for additional information. A transition between vertices of the position graph is performed specifically by PUSHING a box, not by moving Stas. 2. Traverse the position graph using BFS with A* according to the g+h principle, where g is the exact cost of the path from the starting point to the current vertex, and h is a heuristic estimate from the current vertex to the final state. 3. Check for repeated visits to vertices of the graph using a hash table (implemented independently, with no STL containers, as they reduce performance and increase memory usage). 4. Store all examined boards in a fixed-maximum-size priority queue, which I implemented as a heap with K children at each node (K does not necessarily equal 2; it turns out that for this problem K = 4 or 6 is more advantageous). 5. To quickly find all cells of the connected component reachable by Stas from his current position without pushing boxes, you should use not bfs with a queue, but a wave algorithm on bit masks. const uint64_t M36 = (1ULL<<36)-1; Free cells: opened = ~(walls | boxes) & M36; Starting from the player's start bit, we expand the region through neighboring cells until a fixed point is reached. r = start; do { old = r; r |= neighbors(r) & open; } while (r != old); 6. Generation of all possible box pushes from the current position. Instead of a "each box X four directions" loop, for each direction one 36-bit mask of boxes that can be pushed is constructed. In the general case, the condition consists of three factors: the cell contains a box + behind the box there is a cell reachable by the player + in front there is a free cell. These sets are combined through AND after the required shifts. Then only the set bits are iterated over: while (z) { int q = ctz(z); z &= z-1; ... } This is especially efficient because the board is small, while most boxes cannot be pushed in a given direction. 7. Before the main search, immediately after reading the board, for each goal cell a BFS for one box is built in the reverse direction. The other boxes are ignored, but walls and push geometry are taken into account: for a box to be pushed from the previous cell into the current one, both a cell for the box itself and a support cell for the player are needed. We obtain pullDist[goal][cell], as well as pullMin[cell] - the minimum number of pushes to any goal, mask_r[cell] - a bit mask of goals that a box from this cell is capable of reaching at all. If mask_r[cell] == 0 and the cell is not a goal, a new box in it is statically dead. This is much stronger than a simple corner check. 8. Fast heuristic update: on a push, exactly one box q->d moves. Therefore h is not recalculated over all boxes, h_new = h_old - cost[q] + cost[d]. After push q->d, it is not always necessary to perform a full flood fill to determine Stas's component. The old region R changes as follows: d becomes occupied, q becomes free, and the player starts from q. If d did not belong to R or had no more than one neighbor from R, removing d cannot split the component into two parts. Then R can be corrected locally and expanded only through the newly freed q. 9. Before adding a new position to the priority queue, of course, it is worth checking it for unsolvability. The key point of this problem is that you should not be afraid of complex and time-consuming methods for pruning bad positions, the main thing is to prune as many of them as possible. Even solutions that took every 4 by 4 square on the board, fed it into a trained neural network with 2 hidden layers of 60 neurons each, and asked it whether this 4 by 4 combination was unsolvable or not passed within the time limit for me, although it would seem that this already involves 9 * 3600 float multiplication operations (at least), and doing this for every board would take a very long time, but NO, IT WILL NOT, if FEW of those boards remain. So, this is how I pruned bad positions: (!!!) Important note (!!!) We perform the unsolvability check specifically taking into account the position into which the moved box has entered. There is no need to check the lower corner 2 by 2 square on a 6 by 6 board if we moved a box in the top row. This greatly speeds up the checks.
a) the perimeter of the board (the simplest case - the number of boxes along the perimeter and the number of goal cells along the perimeter; more complex - along each side taking attached walls into account, a set of segments along the perimeter, each with its own mask-based check) b) all combinations of occupied 2 by 2 cells (with wall/box variations) - if it is unsolvable, then entire field is unsolvable (this gives 4 squares to check on a 6 by 6 board, since we will check only those adjacent to the moved box) c) all variants of 3 by 3 combinations that no longer contain 2 by 2 blockages, since they were checked at the previous step, which means that it is enough to check 3 by 3 combinations with an empty central cell, which, of course, may also be a goal (we check 8 such squares, depending on which cell of that square corresponds to the moved box) d) there are very many 4 by 4 variants (you must also remember to take into account that Stas may be either inside the selected 4 by 4 sub-square or outside it, so if the combination is encoded with masks, it takes 49 bits: 16 bits each for the positions of boxes and goals inside the 4 by 4, 16 possible positions of Stas inside and 1 outside, 3*16+1 bits). I implemented a generator of unsolvable 4 by 4 squares taking into account that all cells outside it are made goal cells, since we do not know the context of the board when extracting a 4 by 4 square from it, so goals there could be anywhere, and solvability can also depend on that. Of course, during generation, I did not include in the collection those positions that were already pruned by my perimeter checks and 2 by 2 and 3 by 3 squares, only NEW blockage variants. Generation took a couple of months. This produced about 70 million combinations for the corner placement of the 4 by 4 sub-square and slightly fewer for the placement where the upper corner is in cell (0,1) of the original 6 by 6 board. Of course, such a number of combinations cannot be inserted into the source code as a constant array. I tried to train a neural network, but first of all, it takes a long time to query it for an answer (see above, many float multiplications; networks smaller than 120 neurons did not train at all), and second, it still gives a probabilistic answer and on some Timus tests (especially newly added ones) it may classify a solvable combination (even if only one out of 10000) as unsolvable, and it turns out that pruning such a board just once or moving it to the end of the priority queue is enough to fail to find a solution in time. Therefore, although I managed to fit the solution with the neural network into 4.5 seconds, I discarded this variant as inefficient. An analysis of the resulting collection and identification of common patterns that can be checked simply with bit masks worked much better here; of course, these common patterns did not cover the entire range of bad boards, but I managed to prune about 80 % of the collection. I no longer generated or considered the 5 by 5 and 6 by 6 variants - it is pointless, there are too many combinations. e) Another class of deadlocks is a small rectangular pocket bounded by walls/boxes, with too few goals inside. The player must not be inside the rectangle being considered + internal goals are taken into account + only small sizes for which the checking rule is provable and safe are considered. 10. The order (!) of the board solvability checks and the check for whether the board is in the hash table is important. It is better to first perform the simple checks (up to 2 by 2), then check for presence in the hash, and then perform the complex checks. 11. Not only the box cell is important, but also the side from which the player must approach it. For each (cell,side) pair, msk[cell][side] is calculated - a mask of goals reachable by one box on the static board with the corresponding orientation of the player's approach to the box. From this, a mask of other boxes is also constructed which, together with the new box, create a two-box conflict over the set of reachable goals. 12. An important optimization was that local 2x2,3x3,4x4 windows do not see interactions between boxes located at a distance from one another. For difficult tests, certain four boxes are also selected from all boxes, the remaining boxes are temporarily removed, and if even after removing the other boxes the selected four cannot reach four goals, the full state is unsolvable. Four distinct cells are sorted, the number of combinations is C(36,4)=58905, but solvability also depends on the side/from which component the player can act. Therefore, I store a 36-bit mask of player cells from which this four-box case is solvable in the simplified problem. 13. I had to optimize the hash, making it initially small at 2^16, then increasing it if the combinations grew substantially. I also used _mm_loadu_si128 / _mm_cmpeq_epi16 for hash comparison. It was also important to avoid any dynamically allocated memory: no new/delete, no STL containers. 14. I encountered the problem of insufficient source-code size (64 KB is still too little for large solutions, there is not much room, especially if storing rules for pruning 4 by 4 boards and so on). All such additional static information had to be encoded in a large constant string using alphabetic characters/digits and so on, and decoded during program execution. Variable names had to be kept short, which makes the code difficult to understand, even line breaks sometimes had to be removed to fit into 64 KB. I asked above on the forum to increase the size, this seems like it should not be difficult, but no one heard me. Edited by author 04.09.2026 19:09 Edited by author 04.09.2026 19:20 | | test this if you have WA#8 | LIGHT | 1494. Monobilliards | 30 Aug 2026 20:30 | 1 | try this input 8 2 3 4 1 5 6 7 8 (correct answer for it is "Not a proof") Edited by author 30.08.2026 20:32 | | WA 8 HEELP | ADSK_Y | 1014. Product of Digits | 29 Aug 2026 22:59 | 1 | n = int(input()) if n == 0: print(10) exit() if n < 2: print(n) exit() d = [2, 3, 5, 7] i = 0 ans = [] while n > 0 and i < len(d): p = d[i] while n % p == 0: ans.append(p) n //= p i += 1 if n == 1: n2 = ans.count(2) n3 = ans.count(3) n5 = ans.count(5) n7 = ans.count(7) n9 = n3 // 2 n3 -= n9 * 2 n8 = n2 // 3 n2 -= n8 * 3 n4 = n2 // 2 n2 -= n4 * 2 n6 = min(n3, n2) n2 -= n6 n3 -= n6 print('2' * n2 + '3' * n3 + '4' * n4 + '5' * n5 + '6' * n6 + '7' * n7 + '8' * n8 + '9' * n9) exit() print(-1) | | What complexity your solution has? | Victor Barinov (TNU) | 1527. Bad Roads | 19 Aug 2026 11:26 | 3 | Mine is O( log(MaxH) * N^4 ) O(log(maxH)*M*N*log(N^2)) log(maxH) can actually be log(M) because you have only that many different height values | | A subproblem | Igor Parfenov | 1670. Asterisk | 17 Aug 2026 13:38 | 1 | In my solution I had to solve following interesting subproblem. Given an array. There is somewhere a unique cutpoint in this array. We don't know where, but we can check, if x is a cutpoint in O(1). We have to find this cutpoint, split array in two parts and do the same recursively on both parts. We need to do it faster than in O(n^2). Solution: For a segment (l, r) check for cutpoints in following order: l, r, l+1, r-1, l+2, r-2, ... | | What a test 3? | SamGTU7_MASHENTSEVA_ELENA_ALEKSEEVNA | 1884. Way to the University | 13 Aug 2026 12:18 | 3 | Answer always should be >= 0. Add even more additional checks I guess these should help 1 8 1 1 Answer: 0.00 1 8 1 3 Answer: 0.00 1 8 1 4 Answer: 2.34 1 8 1 15 Answer: 2.34 1 8 1 16 Answer: 0.00 | | Hint for inc and dec case | 🎧 Vadim Barinov \Frez_Fstilus/'``' :) | 1965. Pear Trees | 12 Aug 2026 16:03 | 1 | Let's use pref_m[i][x], pref_le[i][x], suff_m[i][x], suff_le[i][x] where: pref_m[i][x] - on [0;i) elements > x are in decreasing order; pref_le[i][x] - on [0;i) elements <= x are in increasing order; suff_m[i][x] - on [i;n) elements > x are in increasing order; suff_le[i][x] - on [i;n) elements <= x are in decreasing order. There is inc-dec-solution if and only if there exists some pos and val such that pref_m[pos][val], pref_le[pos][val], suff_m[pos][val] and suff_le[pos][val] are all true. In order not to get ML you need to remove either positions or values from these arrays. It's your call to chose | | WA4 | Solver | 1738. Computer Security | 12 Aug 2026 12:17 | 1 | WA4 Solver 12 Aug 2026 12:17 11 may yield 1 twice via deletion | | It's very beatyfull problem. Thanks | KostyaRychkov`~ | 2105. Alice and Bob are on Bikes | 10 Aug 2026 11:10 | 2 | | | If one of players is waiting, meeting still takes place | bidzilya | 2105. Alice and Bob are on Bikes | 7 Aug 2026 22:15 | 1 | Test case is mentioned in other topic 10 10 10 10 1 1 0 10 Answer is 10 | | some tests | __Andrewy__ | 1905. Travel in Time | 5 Aug 2026 10:30 | 3 | 1) 4 4 1 2 9 15 1 4 0 8 2 3 20 30 3 1 31 0 1 4 9 30 -> 4 1 3 4 2 2) 2 3 1 2 0 5 1 1 110 80 1 1 90 0 1 2 100 6 -> 3 2 3 1 3) 3 6 1 2 50 55 2 1 55 40 1 2 0 1 1 3 41 80 3 2 80 12 2 1 15 0 1 2 49 7 -> 6 1 2 4 5 6 3 n= ; k= ; m=n*k <=100000 ------------------------ n m 1 2 1 1 1 2 2 2 ....... 1 2 k k 2 3 1 1 2 3 2 2 ....... 2 3 k k ....... ....... ....... n 1 1 0 n 1 2 1 n 1 3 2 ....... n 1 k k-1 1 1 k 0 --------------------------- for n=3, k=2 Ans. 2 4 6 1 3 5 Thanks, 3rd test helped to find a bug (I didn't register start/end times, so would output just 1 2 4 5) | | Poor centipede :-D | Brooklyn | 1876. Centipede's Morning | 5 Aug 2026 09:52 | 3 | One of the cutest problems in its statement :) | | Understanding the solution | MARAZ MIA | 1876. Centipede's Morning | 5 Aug 2026 09:49 | 4 | After so many calculation and math I have solved the problem..... Here we can have two worst cases... Case 1: having all the right shoes first.so here needed time is 2*b and we have now all the left shoes remaining...so total time is 2*b+40... Case 2: we may have 39 right shoes so time needed here is (39*2=78)...then we have only one right foot left but we may encounter all the left shoes and here needed time is 40+2*(a-40)....> 40 for the first 40 shoes and 2*(a-40) is for the remaining shoes as they needed to be thrown away...then we have the only one right foot left and it need 1 second... so total time = 78+40+2*(a-40)+1 = 119+2*a-80 = 2*a-39 ans=max(Case 1,Case 2) Edited by author 22.02.2020 03:07 But it's given that both a,b>=40.....so how 39 right shoes can be there? mistake in case 2: 119+2*a-80 = 2*a+39 everything else is correct Edited by author 11.01.2021 22:56 It can be solved with simple DP on number-of-left-picked-slippers x number-of-right-picked-slippers | | Limitation of 64 Kb to source code size | Oleg Vasilenko (Chelyabinsk) | | 4 Aug 2026 13:27 | 1 | Please, extend the limit for the size of submitted solution at least to 128 Kb. It is too hard to compress huge difficult solutions in 64 Kb without code obfuscation. There are some problems in this site that can require big source code (not pre-generated array of answers, but really huge algorithmic approach, like Voronoy diagram in 1369 or Sokoban/Ships) | | WA3 | Solver | 2140. BitMazeCraft | 4 Aug 2026 12:25 | 1 | WA3 Solver 4 Aug 2026 12:25 Forgot to check that cell above the start is empty when jumping | | Test 15, something strange | diver_ru (free) | 1341. Device | 4 Aug 2026 11:15 | 4 | I send program with such procedure: void moveNorth(double dist) { w += dist / rEarth * 180 / pi; if (w > 91.0) n = (n - n) / n; } And got crash 15, but when i send void moveNorth(double dist) { w += dist / rEarth * 180 / pi; } i got accepted. So, i think device can reach north pole with test 15 input data, but it's impossible. In this test the device flies too close to north pole. I got AC instead WA#15 when I changed PI from 3.14159265 to 3.141592653589. And I searched for a numerical mistake for 1 hour :) Ha-ha! Edited by author 03.03.2011 23:16 acos(-1) for the most precise value of PI, but still had WA15 with this code int rlat = (int)round(lat * 180 * 1000 / pi); int rlon = (int)round(lon * 180 * 1000 / pi); while (rlon <= -180 * 1000) rlon += 360 * 1000; while (rlon > 180 * 1000) rlon -= 360 * 1000; printf("%s%d.%.3d\n", rlat < 0 ? "-" : "", abs(rlat) / 1000, abs(rlat) % 1000); printf("%s%d.%.3d\n", rlon < 0 ? "-" : "", abs(rlon) / 1000, abs(rlon) % 1000); Then got AC with this code lat *= 180 / pi; lon *= 180 / pi; while (lon <= -180) lon += 360; while (lon > 180) lon -= 360; printf("%.3lf\n%.3lf\n", lat, lon); So I guess there is something like "-0.000" expected by checker Edited by author 03.08.2026 11:20 P.S: Checked with asserts for "-0.000" and "-180.000" results - it didn't fire. Maybe that stuff with 'round' is wrong way to do it with integers (I actually did that precisely to avoid fiddling with such outputs) | | whats wrong with test 15? | Alias aka Alexander Prudaev | 1341. Device | 3 Aug 2026 11:21 | 3 | Test 15 was incorrect, now it is fixed. 5 authors got AC. It is still not precisely correct, see the other thread | | WA3 | Solver | 1341. Device | 3 Aug 2026 11:06 | 1 | WA3 Solver 3 Aug 2026 11:06 -0.001 -0.002 0 my integer-based output omitted "-" sign in that case |
|
|