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

Автор AlexErofeev, 14 лет назад, По-русски
Странно, что никто еще не написал

Результаты
Задачи

Победители:
1 место - Moscow SU Unpredictable: Kornakov, Kumok, Astakhov
2 место - Moscow SU ST: Rogulenko, Kaluzhin, Fedorov
3 место - SPbSU ITMO 1: Isenbaev, Kapun, Melnikov
  • Проголосовать: нравится
  • +16
  • Проголосовать: не нравится

14 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
Кто-нибудь может рассказать, как решать задачу 2, а то почему-то не получилось сдать... Несколько раз получилось ВА 19, может кто-нибудь сталкивался с таким вердиктом?
  • 14 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится
    Жадный. просто жадно прыгаем от одного бортика к другому, проходя максимально возможное расстояние по блока
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      А почему это правильно?
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        еще умножали все длины на 2 (высота может быть нечетной).

        почему правда - пусть мы оказались в какой то точке на нижней крае. Если через эту точку не проходит бордюр ничего не остается как менять направление. Иначе можем либо дойти до конца блока, либо переключить поле раньше. Если переключим поле раньше, прелетим на другую сторону в точке A, еcли дойдем до конца - в точке B. Если A и B лежат на одном бордюре наши действия равносильны, иначе по второй стороне мы сможем дойти дальше, если сейчас дойдем до конца блока.

        Не очень строго, но вроде понятно.
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Спасибо.

          Мы писали динамику, которая такую жадную идею вроде должна была обрабатывать, не прошло, видимо баг в реализации.
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Вот бы ещё разбор услышать )

И когда дорешивание будет?

  • 14 лет назад, # ^ |
      Проголосовать: нравится +9 Проголосовать: не нравится

    Итак, как поучавствовать в дорешивании:

    Проходим по ссылке http://olympic.nsu.ru/nsuts-test/nsuts_new_login.cgi

    Нажимаем на ссылку регистрации, выбираем из пунктов слово "Тренировки", заполняем данные, затем авторизуемся в системе и выбираем из туров "Интернет-тур XI Всесибирской олимпиады, 3 октября 2010 [ACM]" и решаем в своё удовольствие.

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Как решать первую задачу?
  • 14 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится
    Мы сгенерили все допустимые числа (их оказалось несколько тысяч в худшем случае), и просто написали динамику по всем возможным суммам до миллиона. Прошло - потому что достижимых состояний не может быть очень много :)
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Состояние - это сумма которую мы можем получить? Если так, то, имея цифру 1, мы можем получить все числа от 1 до s. Я не понимаю, за счёт чего будем быстро работать. Я сдал двумя циклами.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Ну вообще я тоже не совсем представляю, почему такие решения не заваливаются, но судя по всему они у многих прошли :)
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        очевидный тест:

        0 9 8 7 6 5
        1111 1000000

        у меня на компьютере выполнился за 25 секунд. Хотя это AC.

    • 14 лет назад, # ^ |
        Проголосовать: нравится +5 Проголосовать: не нравится
      А почему состояний не очень много? у меня получалось чисел около 5,5 К и довольно плотное замощение рюкзака) Я просто писал всякие жадины, эвристики, потом написал тупой рюкзак для проверки решения и он прошел) А как решать 9??? Мы не нашли случая "мнимого эллипса" и "параллельных прямых, решили что их нет.. остальные вроде раз на 20 перепроверили - то есть пересекает ли плоскость центр вселенной, если да, то в зависимости от угла, "точка", "прямая", "2 пересекающихся", и если не пересекает, то от угла - "окружность", "эллипс", "парабола", "гипербола". Как верно то было?
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        У нас +8 по ней из за точности. В решении, которое прошло, все вычисления были в long long'ах. Идея и случаи те же.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        У нас точно такие же случаи. Проблемы там с точностью. Даже если не использовать никаких тригонометрических функций и корней, - всё равно очень сложно запихать (даже с long double в g++). Как только переписали на Java с BigDecimal - сразу прошло.


        Вообще в последнее время мы всё чаще удостоверяемся, что даблам вообще нельзя верить... даже когда координаты целые и до тысячи, могут возникнуть проблемы с точностью, не говоря уж про сегодняшнюю задачу, где все числа могли иметь до 6 знаков после точки.

        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Кошмар!! Я переводил в лонг лонги a = ( ( long long ) _a * 1000000 + 1e-6 ); думал с точностью то все ок
          не успел на яву переписать((( обидно
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            А мы переводили методом считать целую часть, умножить на миллион, дополнить дробную нулями, прибавить. И все ок :)
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            если 1000000 + 1e-6 взять в скобочки должно быть AC:)
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            a = ( ( long long ) _a * 1000000 + 1e-6 );
            Странная какая-то формула, если _a - входное дробное число, то вся дробная часть отрежется, а потом уже на 1000000 умножится.

            Мы так переводили:
            long long a = 1000000*(_a+1e-9);

            Почему 16ый тест не прошло, понятия не имею.
            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится
              Возможно косяк в том, что числа на входе и отрицательными могут быть. В этом случае логичнее 1e-9 отнимать, а не прибавлять, при умножении на 1000000. Мы эту фичу сразу просекли и long long вообще из string получали, а не из double, дабы не париться.
              Хотя наверно можно было и так переводить
              long long a = 1000000*(fabs(_a)+1e-9);
              ибо знаки чисел на ход решения вообще не влияют
              • 14 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                Хм) я тут не так формулу то написал))) ( long long ) - идет в самом конце после ( _a * 1000000 + 1e-6 );
                С отрицательными то да) не подумал) мысль интересная)
              • 14 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится
                В дорешивание я так и не добрался, но наверняка ошибка именно в этом и была. Спасибо.
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Ну там же очевидно, что не влезет. После возведения в квадрат числа до 1000000, а после запятой до 10-12. Разве нет?
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Ну нам всего лишь надо сравнить два числа на равенство. Казалось бы, уж 12-то знаков long double должен держать, если все операции - это умножение и сложения.
            • 14 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              Кто сказал что там 12 знаков? Сказано, что числа до тысячи и в их записи не более 6 знаков после точки.

              То есть в худшем случае 999.999999 - 9 значащих цифр. При возведении в квадрат получается 18 значащих цифр. long long держит 18 знаков, а double держит не более 16 значащих цифр.

              На  long long задача заходит.

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

          Писали в double'ах на с++, даже не в long double'ax

          Был sqrt, потом от него ещё atan2...

          Со 2ой попытки сдали.

          Заслали - WA 16, поправили eps с е-9 на е-13, зашло :)


          А вообще задача в long long'ax решается, ява не нужна, там квадратов коеффициентов достаточно, чтоб всё понять, но на контесте мы не догадались.

    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Динамика по всем суммам - это рюкзак?
      Мы написали рюкзак и он не прошел по времени. Тогда мы написали BFS и он прошел. Видимо суть в том, что не надо идти по всем суммам, а только по тем, которые можно набрать.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        В худшем случае набрать можно все суммы (многократно снимая по 1, например). А число переходов при этом в худшем случае 4^6. Так что bfs оптимизации не дает :)
        • 14 лет назад, # ^ |
            Проголосовать: нравится +6 Проголосовать: не нравится
          Хм... Ну вот что можно сказать:
          Как устроен БФС,  каждый следующий получается за больше равное число ходов, чем предыдущий. Следовательно отнимать по 1 будет с самым малым приоритетом, мы будем отнимать тот макс который можем. В большенстве случаев ответ получается маленьким(количество чисел в ответе). По этому тест который заломает БФС, подобрать крайне сложно, или вообще не возможно.
          • 14 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            Вот скажем тест.

            0 1 3 5 7 9

            2222 999999

            Существующие цифры: 2, 4, 6, 8. Понятно, что ответ -1. Четными цифрами нечетное число не набрать. А просмотреть все состояния тут придется, потому что как не перебирай (сверху или снизу) отсечься в наглую нельзя.


        • 14 лет назад, # ^ |
            Проголосовать: нравится +3 Проголосовать: не нравится
          вообще то если можно снимать по 1, то можно и по 11 и по 111 и т.д. А бфс естественно выходит, как только дошел до конца
    • 14 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится
      состояний может быть 1000 000 и максимум 4 цифры , например 1 2 3 4 итого имеем 4^6 переходов 1000000 * 4096 - многовато. Прошло потомучто тесты слабые либо ТЛ больше чем нужно.
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Я после двух WA 3 отправил такое решение и думал, что будет TL. Может они в условии вместо 6-й степени 5 написали?
        • 14 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          У нас кстати тоже WA 3 был, пока мы все отсеки не поубирали и не отправили самое наглое решение :)
  • 14 лет назад, # ^ |
      Проголосовать: нравится +4 Проголосовать: не нравится

    в первой задаче главное понять одну важную особенность тех чисел которые мы можем снимать с карты, это то что в любой позиции может стоять любая цифра из множества рабочих клавиш. делаем динамику d[x][pos] x - сумма, pos - позиция очередной дописываемой цыфры. первый параметр до 10^6 второй от 0 до 6, мы дописываем цыфры по порядку, нулевую, первую вторую и т.д, стоимость дописания цыфры равна 0, стоимость перехода к новой снимаемой сумме равна 1.

    я написал бфс. 6 * 10^6 состояний, переход за dig.size() + 1

    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Фишка: можно просто перебрать все числа до 1000000 и выбрать среди них те, которые состоят из нужных цифр. Гораздо легче пишется
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Напишите, как 7ую делать, кто знает как.
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Делаем такого хитрого Гаусса: каждый раз выбираем из всей подматрицы элемент, который делится на наименьшую степень p, переставляем его swap'ами строки и столбца в текущий угол и дальше как обычно (ясно, что на этот элемент всё остальное можно по-человечески разделить, сократив на степень p). После Гаусса смотрим на получившуюся матрицу. Если правые части уравнений делятся на слишком маленькую степень p (по сравнению с соответствующими диагональными элементами), то нет решений. Иначе каждый диагональный элемент умножает ответ на px, где x - максимальная степень p, на которую он делится (за исключением 0 - для него pq). Восстановить какое-нибудь решение ещё проще - делаем все свободные переменные 0, дальше обратный ход Гаусса.
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Илья, а не подскажешь как 10-ую делать?
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        10ой у нас занимался Аким, лучше его спросить (я только знаю, что там был бинпоиск, но что-то мне подсказывает, что эта информация не очень ценная :))
      • 14 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Да, как сказал  ilyakor в этой задаче бинпоиск по ответу. А для фиксированной скорости уже не сложно жадным алгоритмом понять, через какое наименьшее время мы добежим до конца каждого из лифтов. Для того чтобы убежать от бабки - каждое из этих времен Остапа должно быть меньше соответствующего времени бабки.  (Единственное, что надо заметить, что так как периоды целые числа, то при расчете, когда лифты встретятся достаточно посмотреть в будущее на НОК(T1, T2) секунд).

        Так что сложности возникают только на этапе реализации :).
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Мы не сдали, поэтому уверенными в идее быть не можем.

    А идея такая. Имеем систему линейных уравнений Y=AX. Пустим на ней Гаусса (без делений, - для обнуления какого-то коэффициента будем умножать две строки до их НОКа). В результате могло не найтись диагональной матрицы - если матрица A вырождена. Т.е. в результате первые rang строк будут содержать выражения первых rang переменных, выраженных через остальные n-rang переменные; остальные строки будут нулевыми (правые части в них тоже должны быть нулевыми, иначе - сразу ответ 0).

    Итак, мы получили, что есть rang переменных, выраженных через остальные:

    Учитывая, что переменные xrang + 1... xn могли принимать любое значение, получается, что ответ - это количество таких их наборов, которые позволяют найти соответствующие x1... xrang (поскольку, грубо говоря, обратные по непростому модулю есть не ко всем числам).

    Вообще, чтобы у модульного уравнения

    a· x = b  (modm)

    было решение, необходимо и достаточно, чтобы b делилось на gcd(a, m).

    Применительно к нашей задаче - мы получаем, что требование существования решения эквивалентно системе модульных уравнений:

    Количество решений этой системы и есть ответ на задачу. Но получилось, что мы пришли почти к такой же задаче, что и была. Единственное что - это то, что модули у каждого уравнения свои, но можно домножить коэффициенты каждого уравнения так, чтобы все модули стали pq.

    Итак, мы свели исходную задачу к эквивалентной, но уже меньшей размерности. Запускаем решение рекурсивно от неё, потом подставляем в формулы для восстановления первых rang переменных, чтобы в итоге сгенерить ответ. База рекурсии - когда передаваемая матрица имеет нулевой ранг, тогда надо вернуть (pq)n.


    P.S. У нас WA

    P.P.S. Здесь отвратительная поддержка TeX :)

14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Кто-нибудь может сказать как решать 4 задачу. Можно ли было снимать уже надетую вещь?
  • 14 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Я делал перебор, в какой последовательности надеваются вещи, (к-1)!.

    Нужно учесть, что нужную вещь мы надеваем последней, а другие вещи этого типа не учитывать.

    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      пожалуйста уважайте других это англо-русский сайт!
    • 14 лет назад, # ^ |
        Проголосовать: нравится -13 Проголосовать: не нравится
      Надо же, и на российcкой мове умеете! А я думал, эта задача по-русски не решается ;)
    • 14 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      ок, зафиксировали перестановку, как  порверить что она подходит?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Снимать надетую вещь нельзя.
    Можно использовать динамику d[mask][strengh]
    mask - маска типов вещей которые уже одеты
    strengh - суммарная сила, т.е. сила героя + сила всех одетых вещей.
    d[mask][strengh] = максимальная суммарная ловкость
    для каждого состояния динамики d[mask][strength] перебераем все вещи. Для каждой вещи проверяем можем ли мы ее одеть(rstreght <= strenght && rdex <= d[mask][strengh] && тип вещи не принадлежит маски), если да одеваем и смотрим, что получится, т.е. сможем ли мы улучшить значение для некоторого другого состояния
    Можно сразу в динамику проверять, не смогли ли мы где-то одеть первую вещь
14 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Какое решение у задачи 3?
  • 14 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Возможных множителей, которые войдут в НОК (простые числа до 42 и их степени по размеру до 42) всего 20. Получаем 2^20 вариантов.Порядок множетелей не важен. Для каждой строчки, зная возможные состояния  после предыдущих, просто добавляем новые возможные состояния. В конце из всех состояний остается выбрать максимум.