Задать вопрос
  • Как перевести из матрицы смежности в матрицу инцидентности?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Читайте документацию: https://learn.microsoft.com/en-us/windows/win32/ap...

    This function only affects the layout for the current process or thread.


    Эта функция не может поменять раскладку в системе.

    Попробуйте вот это: https://learn.microsoft.com/en-us/windows/win32/ap...
    Ответ написан
    Комментировать
  • Как вернуть значение на которое указывает указатель?

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

    Нет, в C++ статическая типизация, одна функция может вернуть только один тип. Из List'а вы только Base вернуть и можете. А уже как-то опросив экземпляр класса с помощью виртуальных методов, вы сможете узнать, какого же он на самом деле типа и скастовать к нему.

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

    Или хранте и возвращайте std::Variant, а не указатели на базовый класс.
    Ответ написан
    4 комментария
  • Как хукнуть функцию из другого приложения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Еще проще будет дизассемблировать исполняемый файл и заменить условный переход на безусловный в файле. Не во время исполнения, а на диске. Или вообще в начало функции вставить ret 1 куда-нибудь.

    Вот так прям в памяти патчить, то это опасно. Вдруг функция исполняется в момент перезаписи?
    Но если так хочется, то проще прям в памяти захардкодить return true. каким-то образом.

    Вы там куда-то E9 вставили, и так поменяли код команды на jmp. Но адрес поменяли неправильно. Вставьте в первые несколько байт код ret 1 и все заработает.
    Ответ написан
    5 комментариев
  • Почему clang выдает такой ассемблерный код?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Что у вас за опции сборки (Это же с++, не смотря на теги же?) Оптимизация-то включена? GCC 14 даже без оптимизаций выдает именно второй код в обоих случаях.

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

    Если вы вставите более полный пример кода на godbolt.org, воспроизведете проблему, и поделитесь ссылкой, то, возможно, я смогу вам более детально ответить.

    Edit:
    Разобрались, что это clang c. Такой код он выдает с -O0. Если же оптимизации включены, то он его оптимизирует. Это не недочет или ошибка. Просто, вот такой у него стандартный код. Он вправе засовывать константы в секцию данных, а не вставлять прям в ассемблерный код.
    Ответ написан
  • Чем вызван краш программы?

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

    Попробуйте запустить вашу программу в отладчике с брейкпоинтом по загрузке (видимо, нужно будет windbg использовать какой-нибудь. Не знаю, как это сделать в IDE). Пропустите загрузку всех модулей и потом ставьте брейкпойнт в вашем MainThread. Там пройдитесь до, собственно, вызова auth и посмотрите, по какому адресу оно сделает вызов. Потом, посмотрите в отладчике же, а какой же адрес у auth. Они точно совпадают?

    Еще, а не рабатает ли, если auth в вашем взламываемом экзешнике объявить тоже _stdcall? Не помню, какое там соглашение по вызову по стандарту применяется, но надо чтобы они были одинаковы в коде экзешника и в вашей дллке.
    Ответ написан
  • Когда целесообразно использовать именно такую реализацию DSU?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    DSU выполняет две операции: проверить, принадлежат ли 2 элемента одному множеству; объеденить множества двух данных элементов. Обе за O(log*n) ассимтотически. Это не логарифм, а суперлогарифм, или обратная функция Аккермана. Это - сколько нужно двоек сложить в степенную башню, чтобы набрать n. Она растет так медленно, что ее можно считать константой на практике (она достигнет 4 только при n=2^65536 - вы столько числел не сохраните во всех датацентрах мира).

    Я бы в качестве альтернативной, "тривиальной" реализации рассматривал массив пометок + списки в массиве:
    для каждого элемента храним номер его множества, а для каждого номера храним список всех его элементов в списках (так же, как и в DSU, в одном массиве ссылок на следующий элемент).

    Эта структура компактна по памяти и более быстра, чем ваши хеш таблицы. Тут можно за O(1) проверить, что два числа в одном множестве и за O(log n) объеденить два множества (амортизированно, если перекрашиваем меньшее множество).

    Итак, имеем O(Log*n) vs O(1) за проверку и O(log*n) vs O(log n) за объединения.

    Т.е. вроде бы имеет смысл использовать пометки+списки, если у вас заметно больше проверок, чем объединений.

    Но на практике там выигрыша нет, ибо редко когда у вас сильно больше проверок. Да и, если у вас много проверок, то оценка O(log*n) - завышена, ведь если вы одну и ту же проверку повторяете, то там пути сжимаются и проверки работают уже за O(1).

    Таким образом, DSU от Тарьяна - лучше всех других структур на практике.
    Ответ написан
    7 комментариев
  • Как найти количество помеченных связных графов?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Формула включения-исключения. Берете все графы, где хотя бы одна вершина соединена со всеми (их n*2^(n-2)*(n-1)), вычитаете все графы, где хотя бы две вершины соеденины со всеми (2 раза, ведь они 2 раза подсчитались), прибавляете графы, где хотя бы 3 вершины соеденины со всеми (3 раза)... И т.д.

    Графов, где хотя бы k вершин имеют степень n-1 - C(n, k)*2^{(n-k-1)(n-k)/2}: тут можно выбрать k вершин и для каждого ребра из оставшихся n-k вершин есть 2 варианта - оно или есть, или нет.

    Это будет за O(n log n) решение, если пердподсчитать все факториалы и обратные к им по модулю в задаче. Ну, или O(n^2), если считать сочетания через треугольник паскаля.

    Ражеванное объяснение:

    Сложно подсчитать количество графов где ровно 1 вершина такая полная. Но легко подсчитать те, где k или более таких. Мы их такие зафиксируем и нарисуем от них все ребра. А все оставшиеся ребра в графе могут быть любыми. Во-первых, можно выбрать эти k вершин - поэтому у нас есть множитель C[n,k]. Оставшиеся, незафиксированные ребра идут между любыми двумя оставшимся n-k вершин. Их (n-k)(n-k-1)/2. И каждое может быть или проведено или нет.

    Поэтому всего таких графов, с не менее k вершин: F(k)=C[n,k]*2^{(n-k)(n-k-1)/2}.

    Теперь, как подсчитать графы ровно с 1 вершиной? Можно взять F(1). Но мы насчитали много лишнего, Графы с 2мя такими вершинами мы в F(1) подсчитали 2 раза. Поэтому вычтем 2F(2). Теперь графы ровно с 3 вершинами мы подсчитали 3 раза в F(1) и 3 раза в каждом F(2). Поэтому пока мы их насчитали 3-2*3 = -3 раза. Поэтому прибавим 3F(3). И далее, получится, что графы ровно с 4-мя вершинами мы подсчитали 4 раза (4-2*6+3*4). И т.д.
    Ответ написан
    6 комментариев
  • Какой правильный класс коллекции для хранения сортируемого списка?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Достаточно списка. При принудительном обновлении берите первый элемент из списка. При любом обновлении перемещайте объект(ы) в конец. Можно перед началом из списка элемент удалить, а после конца в конце вернуть.

    Тут вам еще понадобится какая-то структура, чтобы по объекту получить итератор на него в списке. Если у вас объекты каким-то id определяются, то это может быть
    std::unordered_map<int, std::list<Object>::iterator>
    .

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

    А вообще, есть и Lock-free списки. Если у вас обновления сами по себе очень быстрые операции, то такая структура может быть в итоге работать быстрее.

    Edit: простите за C++-ый код. Не заметил, что вопрос с java тегом. В общем, тут нужны какой-то список и hashmap из id в итераторы в этом листе.
    Ответ написан
  • Как посчитать сумму числовой последовательности?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Вы считаете 4 слагаемых, а их должно быть 40.
    Ответ написан
    Комментировать
  • Как записать это выражение?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Да, нижние индексы - это обозначение системы счисления. Так, 110 в двочиной - это 6 в десятичной, или вот то разложение по степеням двойки.
    Ответ написан
  • Отличие int32_t от std::int32_t?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это один и тот же тип. Просто для обратной совместимости, при запихивании его в стандарт, в std::int32_t протащили сишные типы. Вот код.

    Edit: я сначала перепутал, что куда протащили.
    Ответ написан
    Комментировать
  • Что не так в решении задачи?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проверка числа на простоту не так.
    Во-первых, начинайте c n=2, ибо 1 у вас иначе простым числом будет.

    Во-вторых, в вашем случае надо проверять, что n не делится на все предыдущие простые числа. Вложенным циклом. Ну, или решето эратосфена реализуйте.
    Ответ написан
    Комментировать
  • Можно ли сравнить большие массивы по частям?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Можно и по частям. Какой там алгоритм сравнения, если все сразу известно? Два указателя, по одному в каждом массиве. Выкидываем меньшее число из двух - оно уникальное в своем массиве. Если два числа равны - вы нашли совпадение и двигайте оба.

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Завист от того, как реализованы "действия" в каждом окне-игре.
    Если дело на windows, то есть шанс, что окно воспримет за клик получение сообщение WM_MOUSEDOWN/WM_MOUSEUP. Тогда можно просто посылать сообщения в каждое окно параллельно отдельной программой.
    Но для некоторых игр важно, чтобы окно было активно, а некоторые еще и детектируют кучу всего с мышью и надо именно что эмулировать движение мышью через mouse_event, например. Но, в этом случае мышь одна на оба окна, поэтому надо, чтобы оба "скрипта" посылали клики централизовано, через какой-то компонент с мьютексом, который бы вы полнял ровно одно действие в единицу времени.

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

    Нужные функции посылания сообщения и клика мышью - это winapi, но у него, по-моему, есть и обертка даже на питоне в модуле win32 и pyautogui.
    Ответ написан
    Комментировать
  • Что отвечает за предотвращение нежелательной записи в text секцию?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Память помечена, как read-only.
    Ответ написан
    Комментировать
  • Как найти решение для задачи?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Rsa97 правильно написал про геометрический смысл. Но есть более быстрое решение за O(n log n), использующее метод заметающей прямой.

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

    Если числа в задаче большие или нецелые, то сначала через бинпоиск или хешмап замените все координаты по X и по Y на их порядковый номер в отсортированном массиве (отдельно по каждой оси). Эта операция называется "сжатие координат". Теперь у вас все координаты целые числа от 0 до 2*n.

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

    Для этого каждый прямоугольник (X1, Y1, X2, Y2) создаст 2 события "открылся отрезок с Y1 до Y2 во время X1" и "закрылся отрезок с Y1 до Y2 во время X2". Эти все события вы сортируете по X и в таком порядке обрабатываете.

    Для отслеживания состояния прямой используйте дерево отрезков на минимум с отложенной суммой. Эта структура данных потребует массив на примерно 4n элементов для дерева с 2n листами. Каждая вершина будет хранить минимум на соответсвующем ей отрезке. При открытии прямоугольника вы должны добавить +1 на его отрезок. При закрытии - вычесть 1. Сначала открывайте прямоугольники, если время у событий одинаковое. Учитывайте это при сортировке. Так касающиеся по вертикали прямоугольники не создадут пустых мест.
    Если после обработки какого-либо события вы получили минимум в дереве отрезков 0 и следующее событие имеет большую координату по X - то какая-то часть оказалась не покрыта. Еще есть случай, если первое событие не X1=левая граница покрываемого прямоугольника, или последнее событие - не X2=правая граница всего прямоугольника. Тут тоже покрытия нет.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Разница по горизонтали всегда +2. Значит число из строки 2 будет входить с коэффициентом 2.
    По вертикали разница на -1. Значит число из столбца B будет с коэффициентом -1.

    Итак, формула -1*$B3+2*C$2 - 1 . -1 в конце подбираем так, чтобы в самой первой ячейке оказался 0.
    Ответ написан
    Комментировать
  • Каким алгоритмом воспользоваться для поиска вхождений диапазона чисел в другой диапазон?

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

    Вы каждый отрезок представляете в виде точки на плоскости. Когда приходит новая точка, вам надо в квадрантах относительно нее (левый верхний и правый нижний) найти минимальный номер точки. При нахождени , она удаляется из мтруктуры данных и вы нашли ей пару. Иначе добаляйте новую точку в структуру данных.
    Ответ написан
  • Можно ли так доказывать правильность алгоритмов?

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