Блог пользователя MikeMirzayanov

Автор MikeMirzayanov, 13 лет назад, По-русски

Всем привет!

Сегодня, 23-го октября (в воскресенье) в 12:00 (по Москве) начнется онлайн трансляция недавно завершившегося четвертьфинала Южного подрегиона NEERC. Два дня назад это соревнование состоялось в Саратове на базе Саратовского ГУ, а сегодня вы можете принять участие в нем неофициально. Участники официального соревнования будут присутствовать в текущих результатах. Условия задач будут доступны как одним PDF-файлом, так и в HTML по одной задаче. Для участия перейдите на сайт http://acm.sgu.ru.

После контеста здесь можно будет обсудить задачи. Надеюсь они вам понравятся.

Председатель жюри четвертьфинала,
MikeMirzayanov

  • Проголосовать: нравится
  • +51
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится -6 Проголосовать: не нравится
а где можно найти русский текст задач?
13 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится
Расскажите, пожалуйста, как решать H?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится
    Утверждение 1. Ответ - все делители некоторого числа.  Более менее должно быть очевидно.
    Утверждение 2. Ответ - делители числа gcd(|ai - aj|) по всем i,j где a_i коеффициент на который умножается i-ая буква. Это так, потому что существуют два числа с такой разностью.
    Утверждение 3. Ответ все делители gcd(gcd(|ai - aj|), b) - где b - произвольное значение этой строки.
    Это получает какой-то большой тл. Лечится тем, что заменим поиск делителей на разложение на простые и очевидный переборчик. Почему это быстрее не знаю.
    • 13 лет назад, # ^ |
        Проголосовать: нравится +5 Проголосовать: не нравится
      Сделаем 10 000 итераций, генерируя случайное число из букв. Находим их НОД и раскладываем на множители способом выше.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        У меня прошло вообще тупое решение: берем случайное число из букв, так чтобы первые 2 цифры были 11 или 10, затем раскладываем на множители, перебирая простые до корня, а потом просто проверяем, подходит ли каждый делитель. Чтобы узнать, подходит ли делитель, можно взять 500 рандомных чисел, которые подходят под шаблон и сделать проверку только для них.

        Единственная оптимизация: если какое-то число подошло, то его делители я уже не проверяю, т.к. они точно подходят.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          В принципе одно и то же, но мне кажется у твоего метода вероятность ошибки больше, т.к. надо чтобы ответ был правильным для каждой подзадачи.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Ну, в принципе, понятно, почему быстрее - во-первых, всегда быстрее, когда у ответа более двух делителей, а здесь у ответа обычно много мелких делителей. Мы получили ТЛ 89 и немного времени не хватило сделать разложение на простые и переборчик.
  • 13 лет назад, # ^ |
    Rev. 5   Проголосовать: нравится -21 Проголосовать: не нравится
    Легко свести эту задачу к нахождению наибольшего общего делителя, или gcd
    Первое решение - взять несколько рандомных чисел, подходящих под шаблон, и взять их gcd. Это работает, несколько команд так и сдали
    Второе решение - если у нас в шаблоне меньше чем 10 различных букв, покажем на примере что нужно сделать:
    Пусть допустим aaababaa
    Если взять сначала a=1, b=3; а затем a=2, b=3, то получим разность получившихся двух чисел 11101011. То же самое проделаем для буквы b, получим 00010100, возьмем gcd у этих двух чисел и получим ответ.
    Если же у нас есть все 10 букв в слове, то утверждается, что существует только три варианта. А именно -слово длиной 10 букв(abcdefghij-для него ответ 9), и что-то наподобие слова aaaabcdefghij-для него ответ 3(то есть четыре буквы одного типа, всех остальных по одному). Покажем, что для остальных слов  из 10 букв ответ 1. Возьмем произвольное слово, не подходящее по первым двум критериям. У этого слова есть такая замена, которая не делится на три. И у него так же существуют такие две позиции, которые являются соседними, и буквы в этих позициях встречаются в слове только один раз(по принципу Дирихле). Возьмем и поставим в эти позиции 1 и 2 поочередно, а остальные позиции менять не будем. Тогда разность между двумя числами будет 9*10^k. Но не на 3, ни на 9 это число не делится, ну и понятно, почему шаблон не делится на 2 и на 5, поэтому доказано.
    • 13 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится -19 Проголосовать: не нравится

      Короче, задолбался исправлять отдельные слова, что непонятно-спрашивайте.

  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Если я не ошибаюсь (не сдавал), то следующее верно:
    Рассмотрим все числа, которые получаются заменой одной буквы на 1, а остальных на 0.
    Если различных букв 10, то вычтем из всех минимальное из них, а само минимальное помножим на 45
    GCD == GCD полученного набора [Он из не более, чем 10 чисел. Вся вычислительная сложность в разложении на множители]

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Вот решение, которое очевидно находит делитель нужного числа. Что он максимальный доказать не смог, но тесты прошло.

    Для каждой буквы алфавита находим коэффициент, на который она домножится в результате (сумма степеней десятки по всем ее вхождениям в строку). Ответ - gcd этих коэфициентов.

    + несколько особых случаев:
    1) 10 разных букв -> 9
    2) 10 разных букв + еще 3 вхождения одной из них -> 3
    • 13 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится -8 Проголосовать: не нравится

      Доказательство именно этого факта чуть выше. Или же вот здесь в комментариях

      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Подскажите, какие могут быть ключевые различия в компиляторах GCC/VSC++? Сдал эту задачу с черти-какого раза, все баг искал(ВА2). Поменял компилятор - ТЛ89, убрал костыли "от багов"  - АС. Использовал только стринги и вектора из STL, выводил через %lld.
        • 13 лет назад, # ^ |
            Проголосовать: нравится +8 Проголосовать: не нравится
          %lld это может быть печально
        • 13 лет назад, # ^ |
          Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

          Путем проб и ошибок нашел. Если одновременно пользоваться cin и printf/scanf, то студия нормально хавает(VS 8 c++), а gcc - нет. Что конкретно там творится - не знаю, но после того как переписал полностью на потоковый ввод/вывод прошло под gcc. Так что, либо синхронизируйте потоки, либо вообще не смешивайте.

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Как решать G?
Я писал bfs по состояниям (состояние = клетка + битмаска, задающая, съедена ли та или иная чёрная фигура).
TL 91 :(
  • 13 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится
    Именно так и сдавалась спокойно. Может быть вы долго проверяли можно ли пойти куда-то?
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Пока писал сообщение содержания "Я делал так, а как же ускорить?" понял, что в каждом положении проверяю не 8 ближайших клеток, а все клетки доски на то, можно ли в них пойти. Печально (
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

yeputons, демон, как ты умудрился сдать в 5:00?

  • 13 лет назад, # ^ |
      Проголосовать: нравится +15 Проголосовать: не нравится
    Колдуем потихоньку :)
    Думаю, виновато округление времени
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Вот если бы сдал на 5:01 - это было бы колдуем :) Где-то для пятичасового контеста были прецеденты.
      (кажется, проверялка ставила время фактической проверки вместо времени посылки).

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Подскажите, пожалуйста, есть ли добивание в этом контесте?
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Какая у вас сложность? У меня со сложностью (2 ^ 14) * (14) * ((15) * (15) + 14) операций проходит.

(Не в ту ветку, ответ на вопрос Malinovsky239)

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Can someone explain how to approach C ?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +14 Проголосовать: не нравится
    ans = 0;
    for seg1 in vertical segments
        for seg2 in vertical segments (index of seg2 > index of seg1)
          {
             curCnt = 0;
             for seg3 in horizontal segments
               if seg3 intersects seg1 && seg3 intersects seg2 
                 curCnt++;
            ans += curCnt*(curCnt-1)/2;
          }
    print ans
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
интересно, как же решается задача А?))
  • 13 лет назад, # ^ |
      Проголосовать: нравится +4 Проголосовать: не нравится
    Переберем все варианты хода для первого работодателя и проверим может ли он выиграть из этой вершины.
    Второй выигрывает, если он может нанять двух крутых программистов раньше первого. Обозначим кратчайшее расстояние между этими программистами за u, а расстояние от первого работодателя до них как x и y соответственно. Второй может их нанять в двух случаях:
    • Если u + 1 < x + y. Т.к. в этом случае второй игрок может выбрать вершину на кратчайшем пути между этими программистами и в зависимости от хода первого игрока, приближаться к соответствующему программисту. В силу неравенства второй игрок наймет обоих программистов раньше первого.
    • Если не существует 2 вершин v1 и v2, таких что они обе лежат на каком то кратчайшем пути между программистами, расстояние до вершины выбранной первым игроком до v1 и v2 равно 1 и расстояния от v1 и v2 до программистов совпадают. Если они существуют, то несложно построить выигрышную стратегию для первого игрока.
    Предподсчитаем кратчайшие расстояния от всех трех программистов, тогда хода первого игрока мы может быстро определить x, y, u.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Не подскажете как решается E?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится
    Во первых, найдем центр дерева. Центр - это середина какого либо из диаметров. Если он на ребре - запомним вариант ответа, когда мы стягиваем это ребро, а потом разбивьем это ребро на 2 куска с очень большой стоимостью.

    Итак, центр дерева в вершине. Выкидываем из дерева все ребра, что не входят в диаметр и подвешиваем на центр. Полученное дерево мы назвали "веник":) ибо все пути от центра до листьев одинаковые. Дальше вполне себе очевидная динамика на венике - наименьшее количество денег, которое надо потратить чтобы на любом пути от вершины до листьев было хотя бы одно удаляемое ребро. Пусть мы все посчитали, ответом будет сумма дп по детям корня минус максимум по детям корня. Дальше остается только построить ответ (не забыв при этом про случай когда центр был на ребре).
  • 13 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится +6 Проголосовать: не нравится

    Решение с разбора.

    Решается динамикой по поддеревьям.

    Найдем центры дерева. Их либо 1, либо 2 штуки.

    Пусть центр один. Пусть из него идут несколько ребер, и в направлении K из них длиннейший путь из центра до некоторого листа максимален. Тогда для уменьшения диаметра нужно уменьшить длиннейший путь в K-1 направлениях.  Подвесим дерево за центр, и запустим динамику, которая считает стоимость уменьшения максимального пути до листа в поддереве вершины. Пересчитывается думаю понятно как.

    Если центра два, появляется еще немножко колдовства, например нужно учесть, что диаметр можно уменьшить, выпилив ребро между центрами.

    UPD: охщи, слоупочина, ну пусть два разбора будет.

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Can anyone explain the tricks in problem H?
I tried the following approach: For each character, constructs a number with digits 0 & 1. The i-th digit is 1 if the i-th character of input string = current character
e.g. aabbaa --> number 110011 and 1100
Result = divisors of GCD(all generated number, and one possible number created by mapping the input string to a valid number)
I found a special case when all 10 digits appear and input string's length = 10. In this case, output should be 1 3 9
Did I miss any cases, or is my algorithm wrong?
Thank you for reading this :)
  • 13 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится
    for testcase aaaabcdefghij answer is 1 3
    in the all rest you are right
    • 13 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      Thanks a lot :)
      I was doing that problem for hours and couldn't think of that case :(
  • 13 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится +4 Проголосовать: не нравится
    If the number of different letter =10, there are only three cases. First is abcdefghij. gcd is 9. 
    Second case is aaaabcdefghij, gcd is 3, and other similar variants of this string.
    In all other cases answer is 1. Let prove it. There is 2 neighboring position, where the letters in this position occur in this world only once (Dirichle principle for string no more than 14 symbols). Let put to this position 1 and 2 alternately and other position let assign random numbers. Then the different between this two numbers is 9*10^k. And it is clear that the string not divisible by 2, 5, 3.
  • 13 лет назад, # ^ |
    Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

    How can you know that brute-force is too slow for this problem?

    I only see 10! different possibilities, and at each possibilitie you just calculate the gcd with the previous gcd. Is the gcd operation (euclidian's way) to slow for this strategy?

    • 13 лет назад, # ^ |
        Проголосовать: нравится +1 Проголосовать: не нравится
      brute is really slow, don't forget that there is 100 test cases in this problem. 
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      I also got accepted using brute force algorithm :)
      Just break after finding around 10^5 numbers. The calculated GCD should be good enough
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Thanks for explaining, I was thinking of O(n^4) .
And how to approach the Berland Chess problem, constraints says solution will be exponential, but looks too complex for me, please elaborate.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    I used dynamic programming. f(i,j,S) = minimum move if the king is in cell (i,j) and need to capture all opponent's pieces in set S.
    The number of states is quite big. I moved to only opponent's pieces' location to minimize the number of state.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Can you tell what exactly will S contain? And if possible give link to your solution.
      • 13 лет назад, # ^ |
          Проголосовать: нравится +1 Проголосовать: не нравится
        S is a bitmask, i-th bit = 1 if we need to capture the i-th opponent's piece, and i-th bit = 0 if we already captured the i-th opponent's piece
        I don't have my code now. I have a bad habbit: deleting my code after got accepted =)
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Okay,  now to move from one state to another, we need to check whether the *king* can move to that state or not, how did you check that? , I will need O(15*15) for that, is there any simpler way to check whether next state is reachble or not ?

          [nice habbit btw. :) ] 
          • 13 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            I pre-calculated that, but it was to simplify my dp function. I think it wasn't necessary in terms of complexity since the number of states is quite small. I even used O(N*N) to calculate the distance to every cell at each state (i,j,S).
            • 13 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              dp will have (2**15)*15*15 states right?
              I guess you are telling it will be lesser, but how?
              • 13 лет назад, # ^ |
                  Проголосовать: нравится +1 Проголосовать: не нравится
                Number of states = 2^15 * 15 since I only moved to opponent's pieces' location. It was small enough :)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Кто-нибудь пофиксите баг с Mono на sgu. См. форум.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Подскажите пожалуйста, я решаю задачу D, мой код http://pastebin.com/WMZX1gxJ поучаю WA on 20.  решала так: искала количество кубиков, которые умещают в своей сумме число n, потом в зависимости от того, четное их число или нет, смотрела можно ли набрать именно n.не могу понять в чем ошибка(
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
     На каждой боковушке у нас будет по 14 точек. Поэтому общая сумма для k кубиков будет 14*k+a+b, где a,b - числа на крайних кубиках. Поскольку 2<=a+b<=12, мы можем набрать сумму n только если n != (0,1,-1) mod 14, и для набора понадобится n/14 кубиков. Ну и разумеется, нужно рассмотреть крайние случаи: если n<30, то мы можем набрать требуемую сумму только если n=21.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Вот решение без частных случаев:
    Пусть ответ равен K. Сумма чисел на всех кубиках (с учетом внутренних стен) - 21*K. Теперь на K-2 кубиках (если они есть) вычитаем сумму на противоположных гранях - 7*(K-2). И еще осталось вычесть сумму на внутренних гранях первого и последнего кубиков, которая может лежать в диапазоне 2 ... 12. Итого ответ к задаче без всяких частных случаев можно выписать следующей формулой:

    min K s.t.
    21*K - (K>2 ? 7*(K-2) : 0) - (K>1 ? 12 : 0) <= N <= 21*K - (K>2 ? 7*(K-2) : 0) - (K>1 ? 2 : 0)
    • 13 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      C частными случаями получается короче :)

      (n<30 && n!=21 || (n%14<2 || n%14==13) ? -1 : n/14);

      PS: Ого, копирование из студии сохраняет форматирование :)
13 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится
А есть какие-то шансы в будущем поменять Solution на Main? Или все контесты с sgu.ru постепенно переедут на Codeforces?
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Помогите пожалуйста решить задачу B.
Пробовал решить перебором без дополнительной сортировки (ТЛ 28) и сортируя банки по деньгам (ТЛ 73) с эвристиками. И подскажите временную сложность задачи?
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Идея - динамическое программирование. Сложность - O(N). Для каждого банка B ищете самый правый банк A левее банка B, который еще можно ограбить. Теперь, если вы грабите банк B, то можете вместе с ним грабить любой банк левее A и включая A. Додумайте сами.

    Если еще нужны подсказки - пишите.
    • 13 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится
      Частичные максимумы == динамическое программирование? I LOL'D.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Никакого лола не вижу. Можно считать, что начинаете решать задачу с одной точки, потом добавляете по одной точке и решаете задачу для расширенного множества. Вот термин "частичные максимумы" вижу впервые.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Кажется, логично, что если частичные суммы - частичные суммы, то частичные максимумы - то же самое, только для максимума ;)
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Спасибо, работает! =)
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
what's the idea for multiswap problem?

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    For any array number of steps does not exceed 2.
  • 13 лет назад, # ^ |
    Rev. 4   Проголосовать: нравится +3 Проголосовать: не нравится

    Magic.

    It's proofable that any array can be sorted in no more than 2 multiswap operations.
    If array is sorted, answer is 0.

    Now, let's suppose that all numbers in array are distinct. So, we can consider this array as some permutation. Have a look at graph representation of this permutation.

    Answer is 1 if this graph contains cycles only with length no more than 2 (we can swap elements of this cycles and sort array this way).

    If there is at least one cycle of length more than 2, answer is 2. You can notice that swapping two elements of some cycle, divides this cycle into two cycles. This way by one multiswap operation you can divide any cycle into cycles of length no more than 2. goto previous paragraph.

    If not all numbers in array are distinct, we can enumerate all identical numbers as consecutive distinct numbers, and apply algorithm above, so we can still sort array in no more than 2 operations. But not any enumeration will form permutation which requires minimal possible amount of operations for sorting. So, I don't know, what exactly should we do if not all numbers are distinct.

    • 13 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      Exactly - try to use greedy matching for sorting in one step, if this fails and two steps are required, you can assume that this is a permutation and use the solution above.

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Подскажите, пожалуйста, алгоритм на задачу С.
Надо ли было в явном виде искать точки пересечения?
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
In problem B I am getting WA on case 8. In i-th index of an array m[] I am storing the maximum amount found in bank i and all banks after i. Then for each bank I am doing a binary search to find the next suitable bank after current and taking the maximum. Code is here. Please help.
13 лет назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится
Обращаюсь к администрации: есть ли способ вытащить сабмиты с acm.sgu.ru? Если нет, сделайте пожалуйста
  • 13 лет назад, # ^ |
      Проголосовать: нравится -7 Проголосовать: не нравится
    Ты же все напечатал. Зачем тебе? :)
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Напечатаны были contest-mode решения. А сегодня написал хорошие, годные решения, посабмитил и осознал, что надо было их сохранять...
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    У меня есть подозрение, что решения сохраняются на некоторое время либо не сохраняются вообще, поэтому думаю такой возможности нет ((
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Please help me with the problems here.
I am trying to avoid double posting. Thanks.