• Доказать рекуррентную формулу. Кто может решить? Что с этим вообще можно сделать?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    В задаче опечатка, там где-то должно быть J(n-2) вместо J(n-1), и в коэффициентах я не уверен.

    По идее в таких интегралах надо интегрированием по частям выводить рекуррентную формулу. Посмотрите на ответ - интеграл равен функции минус какой-то еще, похожий на изначальный, интеграл. Именно так и выглядит интегрирование по частям.

    Осталось поэксперементировать перебирая разные части x^n и корня из квадртатного выражения: что из них интегрировать, а что дифференцировать.

    Интегрировать корень в знаменателе будет очень тяжко, там логарифмы какие-нибудь вылезут и вообще форма выражения будет совсем другой. Попробуйте продифференцировать 1/sqrt(), а оставшеюся часть интегрировать. Или можно домножить числитель и знаменатель на корень, тогда корень можно уже интегрировать, а оставшееся рациональное полиномиальное выражение дифференцировать.

    Еще можно с конца идти - перенесите все интегралы в одну сторону, сгрупируйте. Получите интеграл равен функции. Можно проверить равенство просто продифференцировав функцию.

    Похоже в задании опечатка - там должны быть J(n-1) и J(n-2), потому что дифференцируя вот эту свободную штуку получается (C1x^n+C2x^(n-1) + C3x^(n-2)) / sqrt(ax^2+bx+c). Значит, с другой стороны должны быть линейная комбинация J(n), J(n-1) и J(n-2).
    Ответ написан
    Комментировать
  • Как перемешать между собой слова создав новые?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Т.е. вам надо сгенерировать перестановку заданных слов? Ну без разницы же, что перемешивать: числа или слова.
    Получите массив из ваших слов, разбив строку по пробелам. Потом перемешайте массив стандартным алгоритмом. Потом выведите их через пробел.

    Стандартный алгоритм перемешивания таков:
    for i in range(len(a)):
      j = random.randint(0, i);
      a[i], a[j] = a[j], a[i]


    Тут поддерживается инвариант, что первые i элементов равномерно и случайно перемешаны. На каждой итерации выбирается случайная позиция для нового элемента (возможно последняя и элемент никуда не переместится). Дальше достаточно только лишь поменять новый элемент со стоящим на его месте. Ведь по инварианту все остальные элементы уже случайно перемешаны и в итоге случайно перемешанными оказываются N+1 элементов.
    Ответ написан
  • Как написать свое регулярное выражение?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Без теории тут никак.
    Тут 2 варианта: или стройте конечный недетерменированный автомат (с эпсилон переходами), который соответствует этому регулярному выражению и дальше применяйте стандартный алгоритм проверки. что автомат принимает заданную строку. Или второй вариант: пишите динамическое программирование "соответствует ли вот этот префикс заданной строки вот этому префиксу регулярного выражения".

    Конечный автомат будет и побыстрее работать и памяти меньше требовать.

    upd: ну и, конечно, тут полным перебором рекурсивно можно сделать. Но это будет гораздо медленнее любого из указанных выше методов.
    Ответ написан
    2 комментария
  • Как определить ближайших соседей прямоугольника с заданной стороны на поле с пропусками, без полного перебора?

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

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

    Надо взять какую-то хитрую структуру данных, чтобы хранить все открытые (в данном случае - последние закрытые) прямоугольники на прямой. В моменты открытия/закрытия прямоугольников надо структуру данных обновлять или опрашивать.

    Тут подойдет что-нибудь вроде std::set в C++ - структура хранящая упорядоченное множество объектов, с доступом и изменением за логарифм, умеющая искать ближайший к заданному значению слева и справа (lower_bound, upper_bound). Хранить в ней мы будем вертикальные отрезки, помеченные номерами их прямоугольникв. Не знаю ее аналоги в других языках - нужно что-то реализованное или на binary search tree, или на skip list.

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

    В этой задаче можно забить на правые границы прямоугольников и на их ширину (раз нет пересечений). Соседями каждого отрезка - левого края будут ближайшие к нему левые края каких-то прямоугольников.
    Поэтому вам надо получить все отрезки заданные в виде {x, y1, y2, id} и отсортировать их (сначала по x, потом по y). Потом в этом порядке их обходите и применяйте новый отрезок к структуре данных. Все удаляемые отрезки + 2 пересекающихся сверху и снизу пойдут в список соседних для нового отрезка.

    Этот алгоритм за O(n log n) получит всех соседей для всех прямоугольников.
    Это что-то похожее вот на эту задачку с leetcode
    Ответ написан
    2 комментария
  • Может ли прерывание прервать выполнение конструктора / деструктора в С++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Да, может. Но обычно в самих конструкторах о многопоточном доступе не беспокоятся, потому что пока конструктор выполняется - объекта еще нет и никакой конкурентный доступ к нему невозможен. Если конструктор обращается к каким-то другим ресурсам, то вот те ресурсы должны защищаться от многопоточных проблем как обычно - не важно из конструктора к ним обращаются или из какого-то другого метода какого-то класса.
    Ответ написан
    Комментировать
  • Min max алгоритм или как сделать ползунок сложности в игре?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Можно при просчете вершины дерева игры выбирать не максимальное/минимальное значение из всех детей, а второе с конца с некоторой вероятностью. Значение вероятности задаётся уровнем сложности.
    Ответ написан
    Комментировать
  • Как запретить std:: vector перемещаться?

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

    Еще можно изменить ваш дизайн. Например, вместо vector использовать list, итераторы в котором не портятся от добавления. Или хранить вместо итераторов/указателей на элементы в векторе индексы.
    Ответ написан
    Комментировать
  • Можно в c++ ли работать с памятью через stream?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Класс std::stringstream как раз это и реализует.
    #include <stringstream>
    
    std::stringstream sout;
    sout << "some string " << 42;
    cout << sout.str();


    Но для сериализации эффективнее будет руками записывать данные в буфер через memcopy: все члены структуры по отдельности чтобы не было проблем с выравниванием. Для строк переменной длины надо будет писать еще и их размер отдельно. Для чисел надо аккуратно с порядком байт разобраться и писать их побайтово.
    Ответ написан
    Комментировать
  • Почему часто можно встретить отступление от структурного подхода?

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

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

    1) Проверить, что данный элемент надо удалить
    1.1) Проверить, что элемент не уникальный
    1.2) Проверить, что элемент - не первый среди одинаковых (один-то его надо оставить)
    2) Удалить элемент из массива дописав 0 в конце.

    Все эти пункты выполняются циклом. в первых пунктах будет удобно завести булевую переменную, которая после цикла будет содержать значение проверки.
    Ответ написан
    Комментировать
  • Дано натуральное число N. Определить количество ифр в цифровой записи данного числа,которые имеют наибольшее значение?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Сначала получите цифровую запись числа (подсказка: деление на 10 с остатком даст вам последнюю цифру и число без этой цифры).

    Далее, поскольку в задаче идет разговор о количестве цифр, вам надо подсчитать, сколько раз каждая цифра встречается. Получите массив из 10 счетчиков.

    Ну и потом просто найдите максимальное число в этом массиве.
    Ответ написан
    Комментировать
  • Как позиция объекта соответствует четырёхмерной матрице?

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

    Четвертая координата позволяет записывать одной матрицей повороты/растяжения и сдвиги. Если у вас матрица 3x3 (не "трехмерная" - у нее все так же есть только ширина и высота), то точка (0, 0, 0) всегда останется (0, 0, 0). Ведь на что 0 не домножай - останется 0. Поэтому матрицами 3x3 можно записать только повороты и сжатия, но не сдвиги.

    Поэтому вводят фиктивное четвертое измерение w. При этом удобно считать, что координаты точки (x, y, z, w) - Это (x/w, y/w, z/w). Это еще иногда называют однородными координатами. Еще один плюс этого объекта в том, что им можно описать точки на бесконечности (когда w = 0).

    Вот тут уже можно составить линейное преобразование (т.е. взять матрицу), которое оставляет w нетронутым, но использует его для сдвига:
    x' = a11*x + a12*y + a13*z + a14*w
    ...
    w' = w

    Вот в a14 - как раз и находится сдвиг по оси X.
    Ответ написан
    3 комментария
  • Можно ли бесконечное число планет выпрямить в бесконечную плоскость?

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

    Количество планет - счетное (Можно по спирали их все занумеровать).
    Каждая планета в форме блина - континуум ("количество" точек в плоскости или в круге, или на отрезке).

    Счетное количество континуумов - тоже котнинуум по мощности.
    Плоскость - тоже континуум.

    С точки зрения теории множеств - плоскость и поверхности всех планет равномощны.
    Ответ написан
    5 комментариев
  • Почему T * может работать ощутимо быстрее (~ на 25-30%) в качестве хранилища данных, чем std::byte *?

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

    Создайте 2 функции, которые отличаются только вот в этих вот местах.
    Вставьте код в https://godbolt.org/

    Смотрите ассемблерный код для двух функций.

    Может, срабатывает strict aliasing. Видя тип T сомпилятор понимает, что эта переменная не может быть изменена какими-то другими std::byte в соседнем коде и может, например, пропустить загрузку-выгрузку данных в регистр из памяти.

    Может вообще что-то другое.

    Единственный вариант разобраться - это смотреть на ассемблерный код функций, которые вы и сравниваете. Не каких-то кусков, оттуда надерганных, а функций целиком.
    Ответ написан
    Комментировать
  • Ошибка Unhandled exception at 0x0099B514 in ConsoleApplication15.exe: 0xC0000094: Integer division by zero. Как исправить это?

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

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

    Очевидно, что size/3 оказывается 0, потому что size меньше 3.

    Надо менять логику. Или отдельно обрабатывать случай size = 0,1,2 или не делить на 3. Вообще, неясно, откуда в этом коде 3 вылезло и что оно означает.
    Ответ написан
    Комментировать
  • Почему может быть ошибка во время компиляции?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема вот тут:
    parent.resize(++n);
    glub.resize(n);
    for (int i = 1; i <= n; i++) {


    Выход за границу массива. Неопределенное поведение.
    Вы выделяете массивы длины n (увеличенного на 1) и потом проходитесь от 1 до n (увеличенного на 1). Но ведь индексы в массиве только до n-1.

    Правильно так:
    parent.resize(n+1);
    glub.resize(n+1);
    for (int i = 1; i <= n; i++) {
    Ответ написан
    5 комментариев
  • Как реализовать идентификацию объектов?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    unordered_map<ID, Material>
    Ответ написан
    Комментировать
  • Как превратить подстроку вида "min ( a, b )" в "a min b"?

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

    Решение поумнее, за линию:

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

    Итак, функция, опять же, проверяет, что есть min. Если нет - возвращает всю строку до первой "," или непарной ")" - нужен счетчик открытых скобок.
    В противном случае, пропускает "min", "(". Рекурсивно преобразовывает от этой позиции. Потом смотрит, что после позиции, которую вернула рекурсивная функция, лежит ",". Иначе - ошибка. Добавляет min к ответу, Рекурсивно преобразовывает оставшееся и добавляет к ответу. Проверяет, что дальше после позиции где закончила обработку рекурсивная функция лежит ")". Возвращает следующую за этим позицию.

    Можно не возвращать преобразованную строку, а сразу все функции могут просто дописывать свой ответ в какое-то одно место. А возвращать int - индекс конца. Ну, или длину обработанной части строки - так даже понятнее.
    Ответ написан
    1 комментарий
  • Как вычислить центр дуги окружности?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Знаете 2 точки дуги - знаете длину хорды. Дальше надо на листке нарисовать окружность, хорду и серидинный перпендикуляр. Нарисовать несколько прямоугольных треугольников и найти длину куска от центра хорды до искомой середины. Пусть центр O, исходные точки A,B а искомая точка - M. Середина хорды С. OM = R. OС^2+CB^2=R^2, CM = OM-OC.

    Итого - длина искомого куска CM = R - sqrt(R^2-|AB|^2/4)

    Для нахождения координат M надо взять середину отрезка AB и отложить от нее перпендикулярный AB вектор длины по формуле выше.
    Ответ написан
    Комментировать
  • Ошибка ссылка на резрешенный внешний символ, как исправить в c++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Судя по ошибке, оно не может найти определение внутренних функций curl.

    Почитайте документацию библиотеки, надо в свойствах проекта добавить библиотеку curl линкеру.
    Ответ написан
    Комментировать