We hope you've enjoyed the problems! (Certain problem editorials below may appear a bit late due to Polygon lag)
| № | Пользователь | Рейтинг |
|---|---|---|
| 1 | Benq | 3792 |
| 2 | VivaciousAubergine | 3647 |
| 3 | Kevin114514 | 3603 |
| 4 | jiangly | 3583 |
| 5 | strapple | 3515 |
| 6 | tourist | 3470 |
| 7 | dXqwq | 3436 |
| 8 | Radewoosh | 3415 |
| 9 | Otomachi_Una | 3413 |
| 10 | Um_nik | 3376 |
| Страны | Города | Организации | Всё → |
| № | Пользователь | Вклад |
|---|---|---|
| 1 | Qingyu | 158 |
| 2 | adamant | 152 |
| 3 | Proof_by_QED | 146 |
| 3 | Um_nik | 146 |
| 5 | Dominater069 | 144 |
| 6 | errorgorn | 141 |
| 7 | cry | 139 |
| 8 | YuukiS | 135 |
| 9 | chromate00 | 134 |
| 9 | TheScrasse | 134 |
We hope you've enjoyed the problems! (Certain problem editorials below may appear a bit late due to Polygon lag)
Keeping track of both Codeforces round and online team contest was a doozy, so this is only the best draft of the editorial I have. Missing problems will gradually be added, and existing explanations may improve over time. Hope you enjoyed the problems, and let me know if anything can be explained better!
UPD: okay, all of the problems are out, and most of the bugs are fixed (I hope). By the way, we had a nice discussion with Errichto on his stream about Div. 2 problems, which some of you may find more approachable. Be sure to check it out, as well as other stuff Errichto creates!
(Kudos to Golovanov399 for his neat grid drawing tool)
Hello, Codeforces community!
I'm glad to invite you to Codeforces Round #691 (Div. 1) and Codeforces Round #691 (Div. 2), which will be held on 19.12.2020 12:35 (Московское время). The round will be rated for both divisions.
The problems were taken (mostly) from the ByteDance — Moscow Workshops Online Contest, which is happening at the same time. They were prepared by me, AndreySergunin, and amethyst0. We are very thankful to the testers: low_, kalki411, ecnerwala, Tima, IITianUG, thenymphsofdelphi, mohammedehab2002, namanbansal013, Redux for their time and great feedback. Also big thanks to Bytedance instructors chenjb and EvenImage for testing and reviewing the Bytedance online contest.
ByteDance is a global technology company operating a range of platforms that allow people across languages, cultures and geographies to create, discover and connect. ByteDance has partnered with Moscow Workshops and Codeforces to organize a top tier and exclusive training camp for the International Collegiate Programming Contest. The upcoming Programming Camp will be held in Beijing from February 20th to 26th, 2021.

ByteDance — Moscow Workshops Online Contest is an opportunity to participate as teams in this camp.
You can find more information about this training camp, including registration and prizes at https://programcamp.bytedance.com/.
Important update: please be informed that the Bytedance online team contest ends 25 minutes after the Codeforces round does. For this reason, we ask you not to discuss the problems publicly during that time, until 3pm MSK. Code and testcases public display will also be disabled during that time. Thank you for your understanding.
Scoring distribution:
Div. 2: 750-1000-1500-2000-2500-3000
Div. 1: 500-1000-1500-2000-2250-3500
Final update: thanks for participating, hope you had fun! Let's hear it for the winners:
Div. 1 (the only contestants to solve 5 problems):
Div. 2:
Here's a (now complete) editorial.
Happy winter holidays to all of you, and see you again on the leaderboards!
Heya! I'm going to stream my performance during ICPC Challenge 2020 on my Youtube channel. I'm not great at marathon-style but I'll see what I can do.
I know this is a competition with prizes which you generally can not stream, but ICPC people seem to be okay with this (in fact this wasn't my idea in the first place), so there you go. I still feel a bit weird about this, so I won't try to explain anything I do (help yourself and try to read my code if you want lol). To make it a little less boring, I'm down to talk to everyone in the chat. Drop by and say hello! Unless you want to focus on the competition of course.
Also check out the official Day Zero stream. GL&HF!
Thank you for waiting! I hope you've enjoyed the problems. Let me know what you think in the comments!
UPD: I almost forgot but here are some notes, as well as challenges for all problems. For a lot of them I don't have a solution and would be happy to hear your ideas.
Find a closed formula for the answer. For simplicity assume $$$a \leq b$$$,
As mentioned above, the problem is not that easy in general case when there are a lot of repeated letters. Still, is it possible to do? Any solution faster than brute-force would be interesting, or even some ideas or observations.
I find it much harder to create a good easy problem than a good hard problem. This position in paricular gave me a lot of trouble, we had to scratch three or four other versions. Not to say the result is very inspiring, but the previous ones were even worse...
What do you except to see in a good easy problem, say, up to Div1A? What are you favourite easy problems of this level? I would especially appreciate answers from high-rated coders.
How to minimize the total number of squares for a given $$$n$$$? The squares-on-a-diagonal construction in the first picture is pretty efficient, but e.g. for $$$n=4$$$ the picture in the sample has fewer squares. How does the minimum-square picture look in general?
How to find the smallest number of operations we need to make until there are no more we can make? Any solution polynomial in $$$n$$$ and $$$\log_2 \max A$$$ would be interesting.
It's not hard to construct a test where $$$n/2$$$ spots have to be closed. However, I could not find a test where more that $$$n/2$$$ spots need to be closed, nor do I know of a solution that closes less than $$$4n/7$$$ spots in the worst case. In other words, if $$$\alpha$$$ is the optimal constant such that $$$\alpha n + o(n)$$$ spots need to be closed, we know that $$$1/2 \leq \alpha \leq 4/7$$$. Can I find better bounds for $$$\alpha$$$, or even find its precise value?
Huge thanks to our tester kocko for pointing out many mistakes in an old version of this problem's statement, and even proposing a revision of a big part of the statement which we've adopted. Sadly, many other parts of the statement still were not very clear...
If the first player wants to minimize the number of turns until $$$R(n)$$$ lamps are lit, and the second player wants to maximize it, what is the resulting number of turns $$$T(n)$$$ is going to be? Precise formula would be awesome, but asymptotics or interesting bounds for $$$T(n)$$$ would be interesting too.
What are the minimum and maximum possible answers among all tilings of the board of given dimensions $$$n$$$ and $$$m$$$?
The final version of this problem is due to 300iq who proposed an interesting modification to my initial idea.
Can you solve the same problem in 3D? The breadboard is now an $$$n \times m \times k$$$ parallelepiped, and there are $$$2(nm + nk + mk)$$$ adjacent ports.

Hi!
On Jun/18/2020 17:45 (Moscow time) we will host Codeforces Global Round 8.
It is the second round of a 2020 series of Codeforces Global Rounds. The rounds are open and rated for everybody.
The prizes for this round:
The prizes for the 6-round series in 2020:
Thanks to XTX, which in 2020 supported the global rounds initiative!
Problems for this round are set by me. Thanks a lot to the coordinator 300iq and testers thenymphsofdelphi, Lewin, Golovanov399, Osama_Alkhodairy, gamegame, dorijanlendvaj, HenriqueBrito, kocko, ruban, Origenes, Ilya-bar, rahulkhairwar. Their feedback was a huge help and affected the problemset greatly.
The round will have eight problems and will last 150 minutes.
Scoring distribution: 500 — 1000 — 1500 — 1750 — 2500 — 3000 — 3500 — 3000+1500
Good luck, and see you on the scoreboard!
UPD: the round has concluded, congratulations to the winners:
Check current Codeforces Global series standings here (courtesy of aropan).
You can find the editorial here.
Stay tuned for prizes announcement!
How is self-isolation treating you? I recently found this channel with a guy solving Sudoku-like puzzles. Had a lot of fun trying to solve puzzles for myself, and then watching the pro do it ten times faster while explaining everything. That reminded me I didn't upload to my Youtube for a while, and gave a good impression of how things look from the other side.
So here's me solving an old AtCoder Regular Contest for practice. From my experience I can recommend trying to solve problems yourself before watching me do it. Wasn't in particular hurry this time, trying to explain my thoughts as good as I can. Let me know what you think, and enjoy!
UPD: Спасибо за участие! Топ-200 официальных участников отбора приглашены в Финал соревнования.
Поздравляем победителей!
Отбор Технокубка:
Дивизион 1:
Дивизион 2:
Разбор тут (если не загружается, надо немного подождать).
Разбалловка:
отбор: 500-750+750-1500-2000-2750-3250-3750
второй дивизион: 500-750+750-1500-2000-2750-3250
первый дивизион: 500-1000-1750-2250-2750-3250
Добрый день!
В 26.10.2019 14:05 (Московское время) состоится Отборочный Раунд 2 олимпиады для школьников Технокубок 2020. Раунд будет длиться два часа, участникам будут предложены 7 задач. По его результатам лучшие участники (но не более 45% от общего числа участников раунда) будут приглашены на финальный этап в Москву. Для регистрации на раунд и участия перейдите по ссылке. Не забудьте заранее зарегистрироваться на раунд! Для опоздавших будет открыта дополнительная регистрация.
Зарегистрироваться на Отборочный Раунд 2 →
Соревнование открыто для всех в виде отдельных раундов для первого и второго дивизионов.
Для всех участников всех трех редакций этого соревнования будет пересчитан рейтинг.
Параллельно с Отборочным Раундом будут проведены открытые рейтинговые раунды для обоих дивизионов, в них могут принять участие все желающие.
Напомним, что согласно правилам раундов Codeforces во время соревнования ваши решения будут тестироваться только на претестах (предварительном и неполном наборе тестов), а системное тестирование состоится после окончания раунда. Обратите внимание, что претесты не покрывают все возможные случаи входных данных, поэтому тщательно тестируйте свои программы! После прохождения претестов у вас будет возможность заблокировать решение, тем самым получив привилегию искать ошибки и взламывать чужие решения, но отказавшись от возможности перепослать ваше решение при каких-либо обстоятельствах (например, даже если вы найдете ошибку или вас взломают). Со временем задачи падают в стоимости. После системного тестирования учитываются только полные решения. Подробнее про правила соревнований можно прочитать по ссылкам:
Регистрация на олимпиаду Технокубок еще открыта. Победителей и призеров олимпиады ждут значительные квоты при поступлении в престижные технические вузы России и ценные призы! Если вы — школьник 8-11 классов и пока не зарегистрировались на Технокубок, то самое время сделать это:
Зарегистрироваться на олимпиаду →
После регистрации на олимпиаду не забудьте зарегистрироваться на Отборочный Раунд!
В финал соревнования будут приглашены лучшие участники каждого из отборочных раундов (но не более 45% от общего числа участников раунда).
A few people expressed interest in me answering some questions regarding competitive programming/problemsetting/related stuff. Since I have a bit of free time during these holidays, let's try this. I'll choose a few most interesting questions from comments under this post and try to answer them in a single video.
Ideally a question should not be to broad ("please give us some tips and tricks" is probably too broad) and possible to answer within a few minutes. I probably won't answer a question if it was asked a lot of times here on CF/quora/someplace else. Let's go!
On Oct/04/2018 10:05 (Moscow time), the Codeforces Round 513 by Barcelona Bootcamp (rated, Div. 1 + Div. 2) will start. This is a special round for the Hello Barcelona Programming Bootcamp, in collaboration with Moscow Workshops ICPC. It is rated for all participants, everybody can register on it regardless of a rating.
Hello Barcelona Programming Bootcamp is sponsored by VTB and Indeed Tokyo, with the addition of team sponsors Phaze Ventures, Spark Labs and REMY Robotics.
VTB, the largest international bank based in Eastern Europe, continues to be an official partner of the Hello Programming Bootcamp series, adding further quality to the 3rd edition of the Hello Barcelona Programming Bootcamp by bringing their own participants, as well as by supporting top teams from around the world.
Indeed Tokyo is Japan's branch of the #1 employment website in the world, giving job seekers free access to millions of jobs from thousands of company websites and job boards. As they sponsor for the second year in a row, Indeed continues to offer the best job opportunities to the boot camp participants.
Wish good luck to all the participants!
There will be 8 problems, common for both division. Score distribution: 500 750 1250 1500 1750 2250 2750 3000.
The problems are prepared by me, Arterm and GlebsHP, with assistance from 300iq, ifsmirnov and vintage_Vlad_Makeev. Have fun!
Всем привет! Сегодня, 13 марта в 21:00 MSK пройдет второй отборочный раунд Яндекс.Алгоритм 2018. Перетий в контест можно с сайта Алгоритма.
Задачи подготовлены мной, Михаилом Тихомировым. Я благодарю за помощь с подготовкой задач Глеба GlebsHP Евстропова, а также ifsmirnov, halyavin, kuzmichev_dima, scorpion за тестирование задач.
Всем удачи, увидимся на контесте!
Hi Codeforces!
The Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined) is going to be held on 05 Oct at 9:05 (UTC+2)! The round will be rated for everyone.
This round is organised in collaboration with 2nd Hello Barcelona ACM ICPC Bootcamp 2017 and supported by Sberbank, the biggest commercial and investment bank of Central and Eastern Europe, with over 175 years of history.
150 students from 53 universities, including ITMO, University of New South Wales, St. Petersburg State University, MIPT, Ural Federal University, Tomsk State University, Novosibirsk State University, Saratov State University, Samara National Research, Perm State University, and many other top global universities such as USA’s highest placing team, Central Florida University, along with Canada’s University of Waterloo, high-scoring Asian teams from Hangzhou Dianzi and Singapore, and Tokyo University, as well as Stockholm’s KTH, will be competing as individuals for the online round, which includes those of you from Codeforces!
The past week has been full of intense competitions, job interviews with Sberbank, and contest analysis and lectures by Andrey Stankevich (andrewzta), Mike Mirzayanov (MikeMirzayanov), Gleb Evstropov (GlebsHP), Artem Vasilyev (VArtem) and Mikhail Tikhomirov (Endagorion).
The event is completely international, as teams from all parts of the globe compete and practice side-by-side. They say a picture is worth a thousand words, so here is a selection to give you some idea of what’s happening at our boot camp.
And, once again, we can’t wait to see you all compete on the international stage, smoothing the road towards the April World Finals in Beijing.
The round’s creators are Endagorion, ifsmirnov, zemen and Arterm — team MIPT Jinotega, two-time medalist ACM-ICPC World Final (2016-17). The round is combined for both divisions, will contain seven problems and last for three hours.
Good luck!
Scoring: 250-500-1000-1500-2250-2500-3500
UPD: Thanks for participating, glory to the winners!
We will publish the editorial as soon as the Barcelona Bootcamp activities conclude.
UPD2: the English editorial is here.
A huge breakthrough in approximation algorithms was announced recently as asymmetric travelling salesman problem was shown to allow a constant approximation scheme. See discussion in an article by R.J. Lipton. One of the co-authors was Jakub dj3500 Tarnawski. It always pleases me to see competitive programmers achieving heights beyond CP, in academia and "real-life" problems (recall that OpenAI's bot recently beat human players at 1v1 Dota2, with meret and Psyho in the developers team). Congratulations on an outstanding achievement, Jakub!
A few people have been asking me for tips on practicing. Since explaining this many times is boring, I will be doing a live stream with a small practice routine: virtual round participation and upsolving the problems immediately after (maybe solving something else as well). I'll try to answer your questions as I go, so join in if you're interested.
The stream will start around 16:00MSK on Saturday, September 2nd on my Youtube channel.
UPD: sorry, the stream is going to start at 18:00, not 16:00.
Hello! I've been trying to install moj plugin on a topcoder applet in a new environment. The problem is I'm getting Exception in thread "AWT-EventQueue-2" java.lang.NoSuchMethodError: com.topcoder.client.contestApplet.common.LocalPreferences.removeProperty(Ljava/lang/String;)Ljava/lang/String;... when trying to save preferences of CodeProcessor, at this point:

Pressing the save button doesn't do anything except for raising the exception in the console. Does someone have any information relevant to resolving this issue? Thanks!
Here's my first attempt to participate in a contest while screencasting and commenting in English as it goes, you can watch the video here. Let me know what you think!
UPD: screencast of today's DGCJ round.
На этот раз я решил попробовать писать разбор в спойлерах, как уже делал кое-кто из авторов. Буду рад вашим комментариям о том, стало ли лучше.
Темы: динамическое программирование.
Общий комментарий: это первая среди "сложных" задач контеста. В ней можно помочь хорошее знакомство со стандартными задачами на ДП, но довести решение до финального правильного вида все равно непросто.
Решение: пускай мы можем сдвигать не только вправо, но и влево.
Прежде всего заметим, что сделать сдвиг -- это то же самое, что переместить какой-то символ в другое место. Ясно, что никакой символ не надо двигать больше одного раза, поскольку вместо этого можно сразу поставить его на финальное место и не тратить действия. Кроме того, очевидно, что сдвиги не меняют количество вхождений каждого символа в строку, поэтому в обеих строках посимвольные вхождения должны совпадать.
Посмотрим теперь на символы исходной строки, которые не затронуты ни одним действием, а также на те позиции, где они в итоге окажутся в финальной строке.
Относительный порядок символов должен совпадать в обоих множествах, поскольку мы не переставляем эти символы. Поэтому множества должны соответствовать общей подпоследовательности исходной и финальной строк. Если какое-то решение сделало k операций, то наша общая подпоследовательность будет иметь длину n - k.
Более того, любую общую подпоследовательность длины k можно превратить в решение, которое совершает ровно n - k действий, просто переставив все нестационарные символы на их окончательные позиции.
Мы можем видеть, что минимальное количество действий равно в точности n - k, где k -- длина наибольшей общей подпоследовательности
... стоит подумать о том, в каких случаях ответ может быть больше или меньше этого количества, и попытаться прийти к противоречию, обращаясь к предыдущим спойлерам.
По ссылке выше можно прочитать про алгоритм решения задачи НОП за время O(n2) при помощи ДП.
Ладно, проехали.
Ясно, что количество вхождений каждого символа все еще должно быть одним и тем же в обеих строках. Кроме того, никакой символ не имеет смысл трогать больше одного раза, а неподвижные символы все еще образуют общую подпоследовательность. Тем не менее, из второго примера ясно, что теперь ответ может быть больше, чем n - LCS(s, t) (здесь LCS(s, t) -- длина наибольшей общей подпоследовательности s и t).
Посмотрим на неподвижный символ si и его финальное положение tj во второй строке. Относительно si мы можем только перемещать символы из правой части s в левую.
Выберем букву x и посчитаем количество ее вхождений справа от si и tj, обозначим эти количества A и B. Из рассуждения выше ясно, что должно выполняться A ≥ B. Если мы собираемся сопоставлять в общей подпоследовательности si и tj, то это условие должно выполняться для всех типов букв.
Довольно логично попробовать написать решение с такой же динамикой, как для нахождения НОП, но с дополнительной проверкой на то, что пары соответствующих символов удовлетворяют условию выше. Однако, возникает вопрос: достаточно ли этих условий, чтобы оставить в рассмотрении только корректные решения (а именно, множества неподвижных символов, по которым можно построить подходящую последовательность операций)?
Сходу доказать или опровергнуть это может быть непросто. Это нормальная ситуация, в том числе для опытных участников.
Пускай у вас есть правдоподобная идея, которую вы хотите проверить, но не можете доказать или опровергнуть теоретически. В такой ситуации хороший метод -- запустить стресс-тест: написать тупое медленное решение, в котором сложно ошибиться, и проверить, согласуются ли его ответы с гипотезой на большом количество случайных тестов. Если это так, то гипотеза с большой вероятностью верна, а если нет, то у вас на руках есть контрпример, а с ним бывает понятнее, что делать дальше.
Да!
Нам надо показать, что из общей подпоследовательности неподвижных символов длины k, удовлетворяющей дополнительным ограничениям (см. выше), можно получить ответ (корректную последовательность действий) длины n - k. Покажем для этого, что все остальные символы можно поставить на места. Очевидно, если неподвижных символов нет, то всех можно переставить как угодно, значит, все хорошо.
Посмотрим на неподвижный символ si и соответствующий символ tj второй строки, а также наборы символов A и B, которые стоят справа от si и tj соответственно. Из необходимого условия следует, что
в том смысле, что никакая буква не встречается в B чаще, чем в A. Поэтому мы можем получить B в финальной конфигурации, выбрав среди A нужные символы и расставив их в правильном порядке справа от si.
Что делать с остальными буквами A' = A\ B? Мы должны переместить каждую из них на финальную позицию за один шаг. Вмес того, чтобы решать этот вопрос сейчас, мы можем притвориться, что буквы si больше нет, и присоединить все буквы из A' к группе слева от si в надежде, что за оставшиеся шаги алгоритм разберется, что делать с этими буквами. Этот процесс можно продолжать, пока группы не кончатся.
Решите задачу принципиально быстрее, чем O(n2), либо объясните, почему это, скорее всего, невозможно.
Задача тесно связана с задачей нахождения НОП. Что известно науке о сложности НОП? Как показать, что наша задача не проще, чем НОП?
Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Темы: жадность.
Общий комментарий: задача на аккуратность. Требуется учесть много мелких деталей, но в остальном задача вполне решаемая.
Решение: Раз мы максимизируем число, важнее всего понять, насколько большую цифру можно поставить на первое место. Обозначим d первую цифру n.
В случае 1 на место первой цифры можно поставить y, в случае 3 можно поставить x, а в случае 5 приходится сделать число короче на одну цифру (что в сущности то же самое, что поставить на первое место 0). Во всех этих случаях при поциферном сравнении ответ сразу становится меньше n, поэтому остальную часть можно просто максимизировать безо всяких ограничений, т.е., заполнить ее цифрами y.
Если d = x или d = y, то у нас есть шанс сделать первую цифру такой же, как в n. Тем не менее, нельзя сразу сказать, можно ли достроить ответ до числа, не превосходящего n, смотри, например, случай n = 20, x = 1, y = 2.
Будем идти по цифрам n, пока не встретим цифру d', отличную от x и y, либо конец числа. Во втором случае ответ просто равен n.
Если d' > x, то мы можем продолжить число до конца (можно применить такое же правило, что и для постановки первой цифры). Если d' < x, то число достроить нельзя, значит, мы должны вернуться назад и уменьшить какие-то из более ранних цифр.
Мы можем только уменьшать y до x, поэтому надо найти самый правый y, сделать его x-ом, а потом максимизировать остаток числа (потому что к этому моменту мы уже поставили меньшую цифру, чем на том же месте в n).
Это значит, что n начинается с нескольких цифр x, а потом идет цифра меньше x. Получается, что ответа такой же длины не существует, поэтому надо искать среди чисел меньшей длины.
Это уже несложно самому понять (или посмотреть в спойлерах выше). Ну серьезно.
Видно, что такое решение работает за O(n), потому что оно совершает не больше двух проходов вперед и одного прохода назад.
Рекомендуется проверить следующее:
Сколько (по модулю 109 + 7) существует положительных чисел, состоящих из x и y и не превосходящих n? Решите за время O(n).
Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Темы: хэширование/строковые алгоритмы.
Общий комментарий: задача несложная, но некоторые решения удачнее других в плане времени работы, памяти и простоты реализации, поэтому продуманный выбор решения мог сэкономить много времени на остальные задачи.
Решение: Для начала поймем, почему последовательность Фибоначчи, определенная в условии, не является 1-рекуррентной.
Тогда найдется функция f(x1), такая что f(ai) = ai + 1 для всех индексов i < n. Но для такой функции одновременно должно выполняться f(1) = 1 и f(1) = 2, противоречие!
Предположим, что после каждого вхождения числа x всегда идет одно и то же число y (либо конец последовательности). Это означает, что функция, заданная соотношениями f(ai) = ai + 1, определена непротиворечиво, значит, последовательность является 1-рекуррентной.
Мы видимо, что k-рекуррентность связана с тем, есть ли противоречия в том, какие числа следуют за участками последовательности длины k: если можно найти два одинаковых участка длины k, после которых идут разные числа, то последовательность не является k-рекуррентной. В противном случае, мы можем определить непротиворечивую функцию f(ai - 1, ..., ai - k) = ai.
Можно просто выписать все участки длины k вместе со следующими элементами и поискать конфликты. Это займет O(n3) времени, если делать просто попарные сравнения,
времени, если отсортировать все участки и делать проверки только для соседних,
времени, если сперва захешировать участки при помощи полиномиальных хэшей.
Осталось сделать бинарный поиск по k, итоговая сложность
или
.
Решите задачу:
при помощи простых строковых алгоритмов (без хэшей!)
при помощи строковых алгоритмов посложнее (все еще без хэшей!)Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Темы: жадность, сортировка, реализация.
Общий комментарий: идея решения сама по себе не является очевидной, но кроме этого требуется большая аккуратность, чтобы избежать проблем с точностью, количеством запросов и всем таким.
Решение:
Пускай мы хотим заплатить сколько-то товаров таким образом, чтобы с точки зрения продавца они стоили какое-то маленькое число ε.
Пускай мы хотим тратить только i-ый товар, тогда нам надо заплатить ε / di единиц, так что с нашей точки зрения стоимость будет равна ε·ci / di. Поэтому лучше всего тратить товар с наименьшим значением ci / di.
Разобьем x на маленькие кусочки размера ε и будем выкупать их по очереди. Согласно предыдущему рассуждению, в оптимальном решении мы должны постепенно тратить товары по мере возрастания их значения ci / di до тех пор, пока продавцу не хватит. Товары с одинаковым ci / di можно тратить в любом порядке.
Мы видели, что важнее всего знать порядок сортировки товаров по возрастанию ci / di.
Важно заметить, что нам не надо знать конкретные значения ci / di, если мы научимся их корректно сравнивать для разных товаров. Останется всего лишь применить любимый алгоритм сортировки.
Возможности наши запросов довольно ограничены: ответ -- это просто "да" или "нет", и нам надо научиться сравнивать отношения при помощи таких запросов. Делать это можно так: сперва найдем конфигурацию чисел ai, при которой с хорошей точностью достигается равенство
, после чего будем делать небольшие изменения относительно этой конфигурации таким образом, чтобы равновесие зависело от результатов сравнения ci / di.
Будем считать все ai равными, и запустим бинарный поиск по их общему значению. После 40-50 итераций мы получим равновесное значение практически на пределе точности типа double (ниже чуть подробнее про проблемы с точностью).
Выберем маленькое положительное число Δ. Чтобы сравнить отношения для i-го и j-го товара, сделаем следующие изменения относительно равновесной конфигурации: ai -= Δ·cj, aj += Δ·ci. Значение суммы
изменится на величину
, которая имеет такой же знак, что и разность ci / di - cj / dj. Теперь для сравнения надо сделать всего один запрос (если только мы не стремимся корректно находить равные отношения, ниже чуть подробнее про это).
Мы знаем порядок, в котором надо тратить товары. Теперь сделаем бинпоиск по тому, какой суммарный объем товаров мы заплатим. Из жадных соображений следует, что любой объем надо тратить, начиная с товаров с маленьким ci / di.
Это решение делает порядка
запросов, при данных ограничениях на практике получается около 450.
На этом описание решения по большому счету заканчивается.
Единственная проблема с выбором Δ в том, что если выбрать слишком большое значение, при сравнении отношений измененные значения ai могут выходить за допустимые границы [0, 1]. Мы знаем, что в равновесной конфигурации значение всех ai будет как минимум на 0.1 отстоять от границ. Чтобы изменения не могли вывести нас за границы, достаточно потребовать неравенство Δ max(ci) ≤ 0.1, поэтому подойдет Δ ≤ 10 - 5.
Отметим, что при сравнении неравных отношений значение
будет изменяться как минимум на
от x, поэтому в таких случаях проблемы с точностью нам не страшны.
Печальная ситуация. Такое требование может возникать, например, если сортировать отношения при помощи std::sort с кастомным компаратором, который сам делает необходимые запросы по ходу дела. std::sort делает дополнительные запросы к компаратору, чтобы проверить его корректность, например, транзитивность. Это не только тратит запросы, но и может привести к ошибке выполнения, если компаратор плохо сравнивает равные объекты: на равных объектах компаратор всегда должен возвращать false.
Наше сравнение для равных дробей работает плохо. Дело в следующем: в теории при сравнении значение
не должно поменяться совсем, а на самом деле из-за погрешностей вещественных чисел оно меняется на очень маленькую величину. В результате, значение может непредсказуемо плясать вокруг x, и сравнения будут возвращать случайные результаты (напомним, что в запросе ? никакие погрешности не учитываются!).
Одно из возможых решений: сделать значение
чуть-чуть больше, чем x, чтобы не пострадать от случайных микроошибок.
Также отметим, что многим алгоритмам сортировки (например, слиянием или вставками) вообще не важно, как сравнивать равные элементы, поэтому там такой проблемы нет.
Можете ли вы решить задачу, сделав
запросов, где A -- максимальное значение ci, di?
Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Темы: математика, кратчайшие пути в графе.
Общий комментарий: даже если не получается придумать простого математического решения, всегда можно воспользоваться стандартными графовыми алгоритмами. Изи.
Решение:
Построим граф, в котором вершины соответствуют состояниям (x, y, d), где (x, y) -- текущая точка, а d -- направление последнего шага (на самом деле, достаточно помнить, был ли последний шаг по горизонтали или вертикали). Если предположить, что не надо выходить за пределы квадрата с координатами не больше 100 по модулю, в нашем графе < 200 000 вершин и < 400 000 ребер, поэтому теперь можно просто найти кратчайший путь при помощи обхода в ширину.
Обозначим модули разностей по координатам x и y за Δx и Δy соответственно.
.
Без ограничения общности предположим, что Δx ≥ Δy. Сперва заметим, что нам обязательно надо сделать не меньше
шагов. Действительно, горизонтальных шагов надо сделать не меньше Δx. Поскольку шаги чередуются, то вертикальных шагов придется сделать не меньше Δx - 1. Наконец, заметим, что четность точки (цвет точки в шахматной раскраске) меняется после каждого шага, поэтому нижнее ограничение на количество вертикальных шагов равно Δx - 1, если начало и конец пути имеют разную четность (т.е. тогда и только тогда, когда Δx + Δy нечетно), и Δx, если одинаковую. В сумме получаем ровно искомую оценку.
Наконец заметим, что такого количество шагов достаточно. Для этого сперва придем в точку (Δy, Δy) за 2Δy шагов, повторяя последовательность шагов RU (вправо-вверх), а затем будем повторять последовательность RURD (вправо-вверх-вправо-вниз), пока не придем на финиш. Можно проверить, что мы придем к цели ровно за заявленное число шагов.
Пускай мы ходим по k-мерному Манхэттену, то есть, наше положение задается k целыми координатами, мы можем менять одну из координат на 1 за один шаг, а также не можем два раза подряд менять одну и ту же координату. Найти длину кратчайшего пути из одной точки в другую за время
.
Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Темы: игры, графы, математика.
Общий комментарий: сперва эта задача казалась мне простой, и я ожидал по ней больше правильных решений. Каждая идея по отдельности достаточно несложная, и кода в итоге совсем чуть-чуть. Оказалось, что распутать задачу целиком под силу немногим. Какие у вас впечатления от задачи? =)
Решение:
Для Красного игрока выполняется равенство kR = vR - eR, где vR -- количество красных вершин, а eR -- количество ребер, у которых оба конца красные.
Красный хочет максимизировать kR - kB, что равняется (vR - eR) - (vB - eB) = (vR - vB) - (eR - eB). Заметим, что vR и vB не зависят от действий игроков, и
. Это означает, что для оптимальной игры можно с тем же успехом минимизировать eR - eB.
Пусть на каждом ребре у нас есть счетчик. Когда Красный ходит в вершину, увеличим значения всех счетчиков ребер, исходящих из вершины, на 1. Когда ходит Синий, уменьшим все соседние счетчики на 1.
С одной стороны, ясно, что это равно (сумма степеней красных вершин) — (сумма степеней синих вершин).
С другой стороны, на красном ребре (у которого оба конца красные) написано +2, а на синем -2. На нейтральном ребре написано 0. Поэтому сумма счетчиков равна 2(eR - eB).
Из этого рассуждения следует, что ход в вершину степени d фактически уменьшает наши очки на d / 2.
Теперь ясно, что оптимальная стратегия такая: всегда ходить в вершину наименьшей степени, независимо от хода игры.
Это легко записать в виде решения, которое работает за O(n).
Как играть в эту игру на унициклическом графе (связном графе с n вершинами и n ребрами)? Что можно сказать про сложность этой задачи для произвольного графа?
Решения к челленджам появятся позже, пока что удачи в самостоятельном решении. =)
Буду рад услышать любые ваши мнения в комментариях. Спасибо за участие!
Привет!
Рад объявить, что сегодня, 4 июня в 15:00 MSK состоится третий и последний отборочный раунд соревнования Яндекс.Алгоритм 2017. Ничуть не меньше рад сообщить, что задачи подготовлены мной, Михаилом Тихомировым. Я проработал в Яндексе три года и с теплотой вспоминаю это время в дружелюбной и сплоченной команде. Ура Яндексу!
Этот раунд не смог бы состояться без трудов следующих людей:
Лидии lperovskaya Перовской и ее команды, обеспечивающих работу системы Яндекс.Контест,
Максима Zlobober Ахмедова, бывшего сурового координатора Codeforces и нынешнего сурового координатора раундов Яндекс.Алгоритм,
Михаила MikeMirzayanov Мирзаянова и команды Codeforces, поддерживающих систему подготовки задач Polygon,
а также всех сотрудников Яндекса, принявших участие в прорешивании раунда (поля этого блога слишком малы, чтобы перечислить их поименно).
Раунд пройдет по стандартной схеме: 6 задач в случайном порядке на 100 минут по системе TCM/Time. По результатам раунда будут присуждены последние очки GP30, влияющие на состав участников финала (текущие результаты можно посмотреть здесь). Даже если вы не участвовали в предыдущих раундах, шансы на участие в финале еще есть!
После окончания раунда появится разбор задач в отдельном посте. Желаем всем участникам удачи и удовольствия от задач!
UPD: начало откладывается на 15 минут по техническим причинам. Приносим наши извинения.
UPD2: раунд закончен! Вот и разбор подъехал (пока на английском).
Yesterday, on April 23 an Open Cup round — Grand Prix of Moscow Workshop was held. In fact, the same contest was held on April 17, the last day of Moscow Pre-Finals ACM ICPC Workshop.
The problems were prepared by the workshop programming committee: Mikhail Tikhomirov (Endagorion) and Gleb Evstropov (GlebsHP), as well as members of MIPT teams Jinotega: Ivan Smirnov (ifsmirnov), Artsem Zhuk (Arterm), Konstantin Semenov (zemen), and Cryptozoology: Alexander Ostanin (Kostroma), Alexander Golovanov (Golovanov399), Nikita Uvarov (-imc-). We hope you enjoyed solving our contest!
The results can be found on the Open Cup page. Our congratulations to teams SPb ITMO University 1 (Belonogov, Zban, Smykalov) and the veteran team SPb Havka-papvsto (Kunyavsky, Kopeliovich) on solving all 11 problems! Please not that since Java issues in Yandex.Contest are not fully resolved yet, the results are not final and Java submissions may be subject to rejudge.
Here is a link to PDF editorial for the problems, prepared by myself and GlebsHP. Please ask your questions and point out the mistakes in the comment section.
Sorry for the wait! We'll be glad to answer your questions in the commens.
| Название |
|---|


