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

Автор Egor, 16 лет назад, По-русски
26 сентября в 11:00 MSD состоится очередной этап Открытого Кубка. Всем удачи!
  • Проголосовать: нравится
  • +15
  • Проголосовать: не нравится

16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Соревнование окончено. Кто-нибудь может подсказать как сдавалась задача U?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Задача О не сдавалась за куб на паскале, хотя такое же решение проходило на с++ :)
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    Куб проходил на Java. 
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Расскажите, пожалуйста, как вы решали О? В чем неверна эта идея: a[] - квадраты кол-ва билетов, p[i][j] - шанс игрока i выиграть приз j, sum - сумма значений a[].
      for i = 1 to n
        t[i][1] = a[i]/sum;
      for i = 1 to n
        for j = 1 to n
           if (i != j)
             t[i][2] += a[i]/(sum-a[j])*t[j][1];
      for i = 1 to n
        for j = 1 to n
          for k = 1 to n
            if (i != j && i != k && j != k)
              t[i][3] += a[i]/(sum-a[j]-a[k])*t[j]*t[k];
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится +3 Проголосовать: не нравится
        Я писал просто цикл, перебирая победителя первого, второго и третьего и прибавляя к вероятности первого приза первому победителю, вероятности второго приза второму победителю и вероятности третьего третьему перемноженную вероятность. Плюс не перебираем людей с нулем камней и используем отдельные случаи для 0, 1 и 2 человек с камнями. То есть:

        prob:= (a[winner1]/sum)*(a[winner2]/(sum-a[winner1]))*(a[winner3]/(sum-a[winner1]-a[winner2]))
        f[winner1,1]:=f[winner1,1]+prob;
        f[winner2,2]:=f[winner2,2]+prob;
        f[winner3,3]:=f[winner3,3]+prob;
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Мы делали в точности то же самое, но словили по ней -10.
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Да, писали мы на C++, получали WA10.
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится
            Спасибо, разобрался в своей ошибке:-) Нужно было вероятность получения третьего приза считать немного иначе, я умножал на общую вероятность получения игроком k второго приза. А нужно было умножать на вероятность получения второго приза игроком k при условии, что первый приз выиграл игрок j. Теперь вместо ВА 2, ТЛЕ 9... Пишу на С++
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    Может быть вы использовали в паскале тип extended? Действия с ним медленнее, чем с double.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Задачу K можно было сдать читерно. Напишем жадное решение. Оно не будет проходить около 6 тестов из тестсета. Далее пишем перебор с прекращением работы после 7 секунд. Я не нешёл теста, которое бы повалило это решение.

Моё решение честное, но в нём 1200 строк.

16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Интересна задача H
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    валиндынми являются треугольники с углами не более 120 градусов и a, a, 0, где а > 0
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Зачем ограничение в 120 градусов? Во всяком случае тесты проходит и без него.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Значит в задаче были гениальные тесты :)
        По крайней мере у меня проверялось что  c2 <  = a2 + b2  + ab :)
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится

          Я слишком увлёкся вырожденным случаем, что совсем забыл про такие решения. Задача задумывалась как самая простая, поэтому неполнота тестов не так страшна.

          Походу, я 59-м тестом хотел сделать 501 500 1000, но сделал 499 500 1000

        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Земляк! Помоги разобраться с задачей I  (Охота на зайцев).
          Не могу понять, их надо искать, только по генерируему вектору или по всей плоскости?
          А, вообще у меня не проходит 21 тест по времени.
          Вся программа работает быстро. Но как только начинаю проверять сколько точек лежит на заданном луче сразу ТЛЕ. Спасибо.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Откуда 120 градусов? Наш тренер доказал, что любой невырожденный треугольник подойдёт.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      а почему? мне показалось, что не более 90
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится +10 Проголосовать: не нравится

        Ну можно заметить, что оптимальная ломаная - это если мы проведем высоты из вершин треугольника, а потом соединим полученные основания высот. Тогда можно заметить, что если у нас есть любой треугольник, который удовлятворяет строгому неравенству треугольника, то можно провести в нем биссектрисы, а затем через вершины нашей ломаной провести прямые перпендикулярные биссектрисам. Тогда мы получим, что для любой ломаной, которая представляет собой невырожденный треугольник - ответ Yes. Все это видно на картинке 

        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Да, мы тоже склонялись к этому, но порисовав я не получал больше 90 грудусов...=(
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          А задачку J не подскажете, полконтеста пытался свести ее к парадоксу о днях рождениях, ответ для пар получил...а как для троек и четверок?
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится +5 Проголосовать: не нравится
            Врядли можно свести к парадоксу о днях рождениях, но тут можно сделать по-другому. Просто посчитаем вероятность того, что у нас будет S+x работников в фирме, где S=m[2]*2+...+m[s]*s, а x изменяется от 0 до d-P, где P=m[2]+...+m[s]. Нетрудно видеть, что других возможностей для количества работников в фирме нет.
            Тогда вероятность p[x] для количества работников S+x равна
            (S+x)!/((2!)^m[2]*(3!)^m[3]*...*(s!)^m[s]*x!)*A(d, P)*A(d-P,x)/d^(S+x)
            где A(n,k) = n!/(n-k)!.
            После этого чтобы найти ответ достаточно сравнить соседние p[x] и p[x+1] и первое x такое, что p[x+1]/p[x]<1.
            А отношение p[x+1]/p[x] легко посчитать, оно равно
            ((S+x+1)*(d-P-x))/(d*(x+1)).
            Собственно говоря, реализация очень простая, но до решения догадаться не так просто.
            • 16 лет назад, скрыть # ^ |
               
              Проголосовать: нравится 0 Проголосовать: не нравится
              спасибо, надо осознать написанное
            • 16 лет назад, скрыть # ^ |
               
              Проголосовать: нравится 0 Проголосовать: не нравится
              что-то я никак не могу понять, почему в знаменателе числителя(!) стоит (x!).
              посчитаем количество ситуаций, когда люди разбились на классы эквивалентности так, как нам надо. Выберем из d дней (p+x), в которые кто-то рождался. выбирать надо упорядоченным образом, то есть в первые x дней рождались по одному человеку, в следующие m2 дней по два, и т.д. Для определенности скажем, что люди рождались в дни a_1, ... , a_x, a_(x+1),... a_(p+x). Теперь если записать последовательно кто в какой день родился получится слово длиной S+x из символов a_1, ... a_(p+x).  Причем символов a_1...a_x в нем 1, символов a_(x+1),...,a_(x+m2) по два, и так далее. Это и есть тот полиномиальный коэффициент. 
              Ну и все делим на общее количество слов d^(s+x). Вопрос откуда взялся (x!) ?
              • 16 лет назад, скрыть # ^ |
                 
                Проголосовать: нравится +5 Проголосовать: не нравится
                Я считал общее количество наборов людей для которых выполнено условие того, что всего людей S+x, из них m[2] групп по 2 человека с днями рождения в один день, ..., m[s] групп по s человек с днями рождения в один день. Тогда людей с уникальными днями рождения x. Если на время забыть про дни, когда все родились, то имеем размещение с повторением (вроде оно так называется). При этом общая формула для количества таких размещений людей n!/((n1)!*(n2)!*...*(nk)!), где n-общее число людей, а n1,n2,...,nk - размеры различных классов еквивалентности. Подставляя в эту формулу наши данные, то есть m[2] классов по 2,..., m[s] классов по s, и один класс из x человек - те у которых уникальные дни рождения (этих людей мы рассматриваем отдельно от остальных), получаем такое выражение
                (S+x)!/((2!)^m[2]*(3!)^m[3]*...*(s!)^m[s]*x!)
                Это общее количество вариантов распределений на группы, без учета дней, в которые родились люди. После этого нужно учесть дни. Для P групп нужно выбрать по дню - это A(d,P). И для оставшихся x людей нужно выбрать x дней - это A(d-P,x). Вот откуда взялась эта формула и x! в знаменателе числителя.

                • 16 лет назад, скрыть # ^ |
                   
                  Проголосовать: нравится 0 Проголосовать: не нравится
                  все понял, спасибо. В моем решении я выбрал дни для каждого из людей, у которых уникальные дни рождения, а потом еще перебирал их перестановки в (S+x)!.
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Верно, только почему-то не заходит простая проверка на невырожденность. Почему? И зачем в задаче отрицательные величины?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится -8 Проголосовать: не нравится
    Очень глупая задача. 
    Если Стороны_Неотрицательны И (Правило_треугольника или Одна_сторона_нулевая_а_другие_равны)
    Напечатать Да
    Иначе
    Напечатать Нет
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Интересно, как решать задачу D. Мы сдали хешами и в решении порядка 200 строк кода. Но судя по результатам, многие сдавали задачу довольно быстро, поэтому может быть есть другое решение?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    В авторском 222 строки :)

    Но как я понял, можно сдать, если за логарифм считать хеши строк длины около 1000000 для каждой вершины. Это можно легко пересчитывать, имея хеши длины 1, 2, 4, 8, 16, ...

  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +5 Проголосовать: не нравится
    Скорее всего все известные решения D используют хэши. Но хэши бывают разные. У меня вышло на 90 строк. 

    Решение такое. Каждой вершине сопоставим строку которая получается если идти из нее. Очевидно что вершины эквивалентны если равны строки. Чтобы не рассматривать отдельно конечные строки все вершины у которых исходящего ребра  направим в дополнительную вершину, с новым символом  и замкнутую на себя. 

    Можно показать что достаточно сравнить 10^10 символов строк. Оценим это сверху как 2^40. Осталось посчитать хеш от первых 2^40 символов строки. Делается это так. Посчитаем куда мы попадем из каждой вершины пойдя на 2^i шагов. После чего используя эту динамику насчитаем хеши для первых 2^i символов строки.

    Для перехода формула такая. next[i][j]=next[next[i][j-1]][j-1] для хеша аналогично.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      По-видимому, мы сами себе усложнили решение...

      В нашем решении мы отдельно рассматривали компоненты связности с циклом и без цикла. Тогда в компонентах без цикла можно сразу посчитать все хеши (так как в таких компонентах всегда есть корень и это дерево), а в компонентах с циклом мы считали (n+1)-символьный хеш, при этом отдельно посчитали next[i][j] для элементов в цикле, а потом дфсами из элементов цикла считали оставшиеся части хешей. 

      В общем понятно теперь, как это можно было совсем быстро закодить. Спасибо :)

    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Чтобы не рассматривать отдельно конечные строки все вершины у которых исходящего ребра  направим в дополнительную вершину, с новым символом  и замкнутую на себя.
      Этот новый символ можно сделать нулём, тогда этот частный случай исчезает сам собой. У нас так же и меньше 40 строк, да.

      А без хешей там, видимо, даже авторы не умеют?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Друзья! А как Вы решали задачу M второго дивизиона о простых числах? Я думаю, что есть какая то формула для подсчета количества простых чисел из заданного интервала. В литературе нигде не нашёл формулы.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Нельзя ли увидеть 11 тест в задаче E? А то он похоже у всех команд падал.
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    У меня возникло ощущение, что недостаточно чётко было условие. Первый тип запроса - максимальное количество очков которое могло быть на промежутке времени [0, ti]. Хотя, возможно, ошибка и в моём решении.

    http://pastebin.com/Cb5KNQJf

    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Оп-па. Да, мы все поняли, что надо очки после ti секунды. Сейчас смотрим на русское и английское условие и все равно не можем понять как надо было до этого догадаться :(

      Сейчас поправим наше решение и пошлем в дорешивание.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится

        Да, нехорошо получилось. До меня только час назад дошло, что этот момент условия я забыл уточнить. Вроде кто читал, у них вопросов не возникало.

        Я думал вы по другой причине не можете её сдать, после 3-х часов я увидел 2 минуса по E, посмотрел своё решение, нашёл у себя ошибку и сразу послал новые тесты.

        Я не видел сабмиты участников, видел бы, послал бы клар. Постараюсь в дальнейшем не допускать таких ошибок.

        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          Мы сейчас поправили и послали решение в соответствие с новым видением условия - TL 27. Так что тесты до 26-го теперь видимо точно правильные )
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится

            Я английский вариант читал мельком, но подумал, что есть разница "for the first t seconds" и "on i second", но не спорю, надо было уточнить.

            Решение через быстрое возведение матрицы не проходит, или вы не так решали?

  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    Кстати, как вы сдали задачу F? Сами догадались или знали теорему?
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Какую теорему?

      Сами догадались. Андрей сначала научился дублировать строку, потом оставлять из длинной строки одну букву, потом при дублировании подставлять перед каждой копией свою функцию, тем самым скрестив первые два достижения - и получилось решение.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Теорема Карри-Шейнфинкеля. У нас на первом курсе был предмет, где на экзамен надо было учить эту теорему. Мне попалось задание, на её применение, я его решил и получил 5. Курс читал Н. Н. Непейвода, кто был на ижевских сборах, скорее всего, его знают.
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Судя по количеству Accepted'ов глупый вопрос, но всё же: как решается P Polygon из второго дивизиона?:-) Считается ли пересечением, если 3 и более диагоналей выходят из одной вершины? Или это допустимо?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    допустимо что 3 и более диагоналей выходят из одной вершины
    мы не досмотрели это в условии
    но с другой стороны если выходят максимум 2 из одной вершины то количество частей может быть различным в зависимости от проведения диагоналей
    ответ формула
    количество точек пересечения (каждые 4 различные вершины дают точку) +
    количество диагоналей  + 1
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится +3 Проголосовать: не нравится
      Брат программист! Я сам дурил голову с этой задачей. Выводил закономерности. А оказывается есть огромная формула для подсчета количества частей при пересечении диагоналей.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Я вообще не считал какую-то формулу шел такой динамикой: допустим мы уже имеем n-угольник, там как-то пересеклись диагонали. Теперь я достраиваю вершину напротив какой-то стороны. Та сторона становится диагональю, но, так как она не пересекает ни одну из ранее поставленных диагоналей нигде, кроме вершин, то следовательно ответ не увеличивается пока. Теперь постараемся провести из вновь поставленной вершины диагоналей. Каждая диагональ разобьет поле на k вершин в одной части многоугольника и m в другой(считайте сами сколько). Проводим эту новую диагональ, ясен пень, пересечет она m*k диагоналей. Проводим все диагонали из этой вершины, получаем ответ))
        • 16 лет назад, скрыть # ^ |
           
          Проголосовать: нравится 0 Проголосовать: не нравится
          а какая сложность в итоге?
          если линейная, то как бысто посчитать все произведения m*k
          • 16 лет назад, скрыть # ^ |
             
            Проголосовать: нравится 0 Проголосовать: не нравится
            А я не помню
            На Екатеринбургском вроде так прокатило, а тут вроде формулку потребавалось вывести. Вроде это будет что-то типа суммы по j j*(i-j-2), ну посчитай, мне лень))) i-это наша динамика
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    там формула
    кол-во диагоналей+кол-во точек пересечения диагоналей+1
    то есть
    (n*(n-3))/2+(n*(n-1)*(n-2)*(n-3))/24+1
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    Мы, например, просто искали ответ как полином четвёртой степени, интерполировали по первым пяти значениям. Наверное, делается проще. А причём тут пересечение?
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Как при чем? В условии задачи сказано, что никакие 3 диагонали не должны пересекаться в одной точке:-) А как вы получили этот полином?
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Паша, есть такой прием. Интерполировать полинов по первым значениям какого-то ряда....но не всегда это работает, но тут было более, чем очевидно
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Ну, вроде понятно, что имелось в виду) Хотя да, можно понять неправильно.

        Мы это никак не получили, интуиция. Эта функция примерно того же порядка, что и количество пар пересекающихся диагоналей, а их четвёртая степень от количества вершин. Значит, если это многочлен, то четвёртой степени. Если кто-нибудь сможет объяснить, почему это многочлен, не подсматривая итоговую формулу (и не выводя её), буду признателен)

        А готовый ответ, конечно, наверняка несложно доказывается формулой Эйлера.
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится
        Простите за мою безграмотность:-) Не знал точного значения слова интерполяция. Вопрос снимается:-)
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится
    А вот и формула,
    rez:=(n*n*n*n-6*n*n*n+23*n*n-42*n+24) div 24;
    проходит на 100%
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
Кто знает хорошие тесты на задачу C?
16 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится
А как T решать?
  • 16 лет назад, скрыть # ^ |
     
    Проголосовать: нравится +3 Проголосовать: не нравится
    динамика по подмножествам.
    • 16 лет назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится
      Можно подробнее? А то та динамика, которую придумал я, была слишком медленной
      • 16 лет назад, скрыть # ^ |
         
        Проголосовать: нравится +3 Проголосовать: не нравится
        Пусть free - это маска незахваченных городов.
        dp[free] - ответ в задаче для такой маски.

        Пусть S(free) = множество всех непустых подмасок маски free.
        Тогда
        dp[free] = 1 / |S(free)| *  (P(x) * dp[free - x] +  (1 - P(x)) * dp[free]),
        где P(x) - вероятность захватить множество x.

        Крайние случаи:
        dp[1] = 1,
        dp[x] = 0, если нулевой бит x равен 0.
        Ответ в задаче: dp[ (1 << n) - 1 ]

        + надо использовать алгоритм перебора всех масок длины n и всех подмасок каждой маски + O(3^n).