Задать вопрос
  • Как оптимизировать поиск в ширину?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Мне в третий раз повторить?
    Ответ написан
    Комментировать
  • Как передать массив в конструктор класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте ошибку внимательно. Дело не в массиве.

    Вместо SegmentTree tree = new SegmentTree(a, n);
    надо
    SegmentTree tree(a, n); или SegmentTree *tree = new SegmentTree(a, n);

    new - создает указатель. Инициализировать им нужно, соответственно, указатель.
    Ответ написан
  • Как посчитать 5 погрешностей?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Найдите разность между myExp и exp - это и будет погрешность. В цикле для всех eps 5 раз. Можно eps вычислять, деля предыдущее на 10.
    Ответ написан
  • Как вычислить количество расположений чисел в строке, которые можно получить из начальной строки любой последовательностью перестановок?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    (Полное условие есть в комментариях к вопросу)

    Алгоритмически тут такое решение: Постройте граф из n вершин, где есть ребро между всеми парами вершин, которые можно менять местами. Подсчитайте размеры компонент связности и перемножте их факториалы. Так, если компонента всего одна, то ответ будет n! (все возможные перестановки из n чисел можно получить так).

    Это работает потому, что в каждой компоненте можно получить любую перестановку. Доказательство: строим остовное дерево в компоненте. Потом берем любой лист и перетаскиваем туда любое число по ребрам остовного дерева. Отрезаем лист от дерева. Повторяем эту операцию пока не останется только одна вершина.

    Если нужно именно математическая формула от P, то тут все сложно, осбоенно, когда числа P достаточно большие. Например, M=6, P1=3 P2=4. Из вершин 3 и 4 вообще нет ребер, а ребро P2 есть только между крайними вершинам. Подобным образом можно создать весьма сложные структуры.

    Однако, если все P меньше равны половины N, то есть простой ответ. В графе будет GCD(P1+1,...,PM+1) компонент связности - все вершины, дающие один и тот же остаток от деления на наибольший общий делитель P+1. И ответ будет что-то вроде (floor(N/G)!)^G*(floor(N/G)+1)^(N%G) (где G - этот самый наибольший общий делитель всех P, увеличенных на 1).

    Это потому, что при достаточно маленьких P, всегда можно отложить их в одну или другую сторону и так в итоге сделать шаг длинной G.

    Доказательство примерно такое: Рассмотрим первую половину вершин. Из них можно отложить вправо самое большое P. А потом влево любое из оставшихся P. Так мы фактически отложили от всех этих вершин любую разность двух P вправо. Если сначала отложить вправо меньшее P, а потом максимальное P назад, то мы отложили ту же разность влево. Из соображений симметричности получается, что мы можем отложить любую разность P от всех вершин в любую сторону. Все разности также меньше половины N. Продолжая этот процесс, как в алгоритме эвклида, мы получим, что можно от каждой вершины отложить G, а значит все вершины с одинаковым остатоком от деления на G принадлежат одной и той же компоненте связности.

    Если какие-то P больше половины (аккуратно сами посмотрите, там +-1 где-то возможно нужно), то я не знаю формулу. Остается только писать DFS на графе.
    Ответ написан
    Комментировать
  • В чем причина возникновения ошибки std::bad_alloc при поиске в графе?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Та же ошибка, что и в прошлом вопросе. Вы в очередь в обходе вширину всегда кладете соседние вершины, а надо это делать, только если они не помечены.

    Вы там еще очередь pop-аете раньше времени.
    Ответ написан
  • Как решить Ханойскую башню с 8 стержнями?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Подобно задаче о 4-х шпинделях. Чтобы переместить самый большой диск на последний шпиндель, сначала надо все меньшие диски куда-то деть. Можно их парковать на 2-ом шпинделе или на 8-ом. Потом подвигать последний диск до 7-ого шпинделя, потом перепарковать часть с 8-ого на 6-ой и подвигать последний диск. Потом назад с 6-ого на 8-ой и оставшиеся со 2-ого на 8-ой. И надо перебрать все варианты - сколько дисков куда пихать.

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

    Чтобы это работало быстро, надо делать мемоизацию и не считать функцию с одним и тем же набором параметров несколько раз.

    Интересно, что ответ растет гораздо медленее, чем для 3-х шпинделей:
    6
    13
    22
    36
    55
    82
    117
    163
    219
    289
    375
    484
    623
    800
    1024
    1300
    1651
    2090
    2643
    3333
    Ответ написан
    2 комментария
  • Как предсказать следующее числовое значение по предыдущим?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Есть целая наука об этом. "Временные ряды", вроде, называется. Там есть куча всяких моделей, типа ARIMA.
    Ответ написан
    4 комментария
  • С: Объясните вторую часть задания?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Наверно, надо сгенерировать последовательность, написать функцию вычисления суммы цифр числа и используя ее найти элемент последовательности с наибольшей суммой.
    Ответ написан
  • Что означает traits_type::eof()?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    type_traits - это имя параметра шаблона, который задан в родительском классе streambuf.

    type_traits::eof() - возвращает код конца файла, для текущего параметра шаблона.

    Вся эта шаблонная магия взялась для того, чтобы можно было читать из файла или char, или wchar, или еще черт знает что, в зависимости от кодировки. Раз читаемые символы могут быть какими угодно, то и код конца файла нужен свой собственный для разных типов символов. Поэтому eof() является частью type_traits в streambuf.
    Ответ написан
    Комментировать
  • В чем проблема обхода в ширину и глубину?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В BFS вы не проверяете, что вершина помечена, и всегда кладете вершину в очередь. А еще там в конце какой-то левый цикл ненужный. Поиск бесконечно циклится и съедает всю память. DFS, похоже, правильный (есть много претензий к стилю, правда).
    Ответ написан
  • Что использовать для формализации рассуждений?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Ну, вы уже правильно сказали, что это граф. Судя по всему вас интересуют компоненты связности в графе.
    Ответ написан
    2 комментария
  • Операции AND, OR, XOR Как проверить биты?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    X AND (2^1+2^2) ИЛИ X AND 230


    Слева же правильно написано, но вы как-то из 2+4 получили 230.

    Х AND (255–2^2–2^7) ИЛИ Х AND 221

    Тоже самое. Правильную операцию сделали, но както из 255-4-128 получили 221, хотя должно быть 123.
    И вместо X пишите A или B в заданиях. Дальше такие же ошибки.
    Ответ написан
  • Как вычислить 2 наименьших нечетных элемента массива в языке С?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Решайте задачу по частям. Сначала выведите все нечетные элементы в массиве.

    Потом (отдельно) найдите в массиве 2 наименьших элемента.

    Потом совместите 2 алгоритма.
    Ответ написан
    Комментировать
  • Как правильно использовать конструктор структуры?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы передаете структуре в конструктор ее саму! Ее еще не создано, а вы ее передаете куда-то. Зачем вам вообще в структуре хранить ссылку на другую структуру? Это вы из питона, что ли взяли? В C++ не надо методам класса/структуры передавать указатель на нее, они средствами языка привязаны уже к экземпляру. Можно обращаться просто к членам структуры напрямую из методов. Или через this->, если есть конфликт имен.
    Ответ написан
    4 комментария
  • Как разбить данный массив?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Все записи скиньте в один массив и отсортируйте по времени. Наверно имеет смысл распарсить даты в какой-нибудь тип Date, или как оно в js называется.

    Потом пройдитесь по массиву, поддерживая счетчик открытых интервалов. Встретили "from" - увеличили счетчик. встретили "to" - уменьшили.

    Если изменили счетчик с 0 на 1, то в текущей дате начало отрезка в ответе. Если изменили с 1 на 0, то тут конец.

    Наверно, надо будет еще отрезки разбить по месяцам потом.

    Еще надо разобраться с тем, когда даты совпадают. Если в одну и ту же дату есть to и from - это же должно считаться одним отрезком? Тогда при сортировке ставьте "from" перед "to" на одну и ту же дату (В сравнении при равенстве дат сравнивайте еще и тип события).
    Ответ написан
    Комментировать
  • Как выполнить размещение k элементов из n?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Гуглите "алгоритм генерации размещений". Находится, например, это.

    Работа с символами ничем не отличается от работы с числами. Во всех языках символы можно сравнивать по их кодам, и в алгоритмах кроме сравнения ничего нет.

    Или можно сгенерировать размещения из {1,2,3,...N} а потом использовать эти числа в размещениях, как индексы символов. Надергайте из заданной строки символы по этим позициям и получите размещение из символов, а не чисел.
    Ответ написан
    Комментировать
  • Как он это "заметил"?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Ну, это известная формула - количество пар среди n объектов. Для самого левого подходит n-1 правых концов. Для второго - их будет n-2. Для последнего - 0. Сумма (n-1)+(n-2)+...+1+0 = (n-1)n/2. Можно через сумму арифметической прогрессии получить.
    Ответ написан
    1 комментарий
  • Как вывести часть bitset-a?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    С битсетом можно работать, как с массивом. У него есть operator[]. Просто пройдитесь циклом в 3 итерации и выводите x[i].
    Ответ написан
    Комментировать
  • Найти позицию элемента в массиве?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    1) Найдите элемент, который встречается наиболее часто. Для этого можно для каждого элемента в массиве подсчитать, сколько раз он встречается вложенным циклом, или лучше воспользоваться каким-нибудь хешмапом для хранения счетчиков. Или отсортировать копию массива и там подсчитать количества вхождений уже очень легко.

    2) Найдите второй с конца элемент. Во-первых, если самый частый встречается всего 1 раз, то ответа нет (-1 по условию). Если он встречается 2 или более раза, то пройдитесь с конца массива и считайте, сколько раз встречали элементы, равные данному. Когда досчитаете до двух - вы нашли ответ.
    Ответ написан
    Комментировать
  • Как доказать, что муха будет бесконечно разворачиваться?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    От противного. Допустим муха в какой-то момент последний раз отразилась (и это до встречи поездов). Она летит быстрее поезда и долетит до другого поезда быстрее второго поезда и отразится там еще раз. Ибо расстояние между поездами хоть и станет меньше, но все еще будет больше 0. Но мы же предположили, что это было последнее отражение. Противоречие.

    И надо еще доказать, почему не может быть последнее отражение когда поезда встретились. Допустим оба поезда и муха встретились в одной точке. А что было в момент предыдущего отражения? какое-то ненулевое расстояние между поездами. Но если с этого момента проиграть, то следующее отражение будет до момента встречи двух поездов. Опять противоречие.
    Ответ написан
    1 комментарий