• Как выполнить сортировку слиянием списков несравнимых элементов?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Гугли "GDI+"
    Это библиотека под винду, которя позволяет рисовать в окнах/на экране.
    Надо получить DeviceContext для экрана, и там рисовать что хочешь.
    Ответ написан
  • Логика игры "Пятнашки" на Python?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Надо, чтобы "четность" перестановки совпадала с четностью финального поля (1).
    Занумеруйте все 16 позиций слева направо сверху вниз.
    чтобы подсчитать четность, рассматривайте каждую пару заполненных позиций (15\*14/2=105 пар) - если числа идут не в том порядке (большее число на позиции с меньшим номером) - то прибавьте 1 к ответу. В конце возьмите ответ по модулю 2. Это и будет четность перестановки.

    Чтобы получить поле, которое можно собрать, сгенерируйте любую перестановку (случайно перемешайте 15 чисел), а потом посчитайте ee четность. Если четность плохая, то поменйте местами любые 2 соседних элемента (выберите случайно, или меняйте первые 2 всегда - на вероятности всех возможных полей это не влияет).

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Надо системное апи использовать. Вы, похоже, под виндой, так что LoadLibraryEx, GetModuleHandleEx, GetProcessAddress вам помогут. Первой вы открываете библиотеку. Второй можно потом пользоваться чтобы получить доступ к уже открытой библиотеке, если вы HANDLE не сохранили куда-то. Третья позволит вам получить указатель на функцию из библиотеки.

    Можно гуглить "имя функции example" и тогда вы найдете в интеренете готовый код, работающий с этими функциями.
    Ответ написан
    Комментировать
  • Как правильно задать интервал для формулы a³+b³=c³+1?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Вы ищите a и b из одного и того же интервала. Но, как вы сами видите, могут быть решения, где разные переменные из разных интервалов. Поэтому один интервал на 1-2000 находит больше решений, чем два интервала 1-1000 и 1001-2000.

    Я думаю, вам стоит вообще внешний цикл убрать и всегда работать только с одним интервалом.

    Можно чуть чуть ускорить решение, если не увеличивать c в цикле, а вычислить его по формуле (an+bn-1)^(1/n). Какая-нибудь функция pow вам поможет. Она даст неуелое число, его надо округлить и проверить, что равенство ввполняется.

    Еще, ваша проблема, что c у вас может быть не из заданного интервала. Надо или жто проверять, или перебирать b и c, считать a, вместо перебора a, b и вычисления c. Потому что a < c. И раз c перебирается в интервале - то и a будет в нем.
    Ответ написан
    44 комментария
  • Нужна концепция, часто ли используете блок схемы скриптов и чем пользуетесь?

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

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

    Все неравенства "==" замените на пару "<=" и ">=".
    Добавьте неравенства 1 < 2, 3 < 4 и т.д. для каждой пары соседних на числовой прямой чисел во входных данных

    Постройте граф: Каждой переменной и уникальному числу во входных данных сопоставьте одну вершину. Проведите для каждого неравнества ребро от меньшей вершины к большей, раскрашенное в 2 цвета: черный, если неравнество нестрогое (<=), белый - иначе.

    Теперь, если в этом графе нет циклов, содержащих белые ребра (строгие неравенства) - то противоречий нет: Все циклы целиком из черных ребер означают, что все вершины имеют одинаковое значение. Можно эти вершины все объединить в одну новую. Раз белые ребра (<) циклов не образуют, то получившийся граф будет ациклическим и можно назначить всем вершинам какие-то числовые значения, удовлетворяющие условиям. Проблема может еще быть, что нет целых решений вроде 1== a < b < c == 2, но это можно потом проверить в топологической сортировке жадно назначая всем вершинам числа. Или противоречия вида 2==3. Тоже решается после получения компонент связности.

    Итак, алгоритм: найдите в этом графе компоненты сильной связности. Потом проверьте все ребра. Если белое ребро (строгое неравнество) имеет оба конца в одной и той же компоненте - вы нашли противоречие.

    Теперь надо постараться назначить кадой компоненте числовое значение так, чтобы не было противоречий. Это можно делать жадно, назначая каждой компоненте минимально возможное значение.

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

    В конце вы получите для каждой компоненты ее численное значение без каких-либо противоречий.
    Ответ написан
    4 комментария
  • Как решить эту непонятную задачу про векторы на C#?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Суть проста: У вас есть два набора из N чисел. Две строки чисел одинаковой длины, если хотите. Надо в каждом столбце (из двух элементов) наверх поставить максимальный, а вниз - минимальный.

    Для решения этой задачи надо уметь в массивы, циклы, условные операторы и уметь поменять местами два значения. Код тривиален: пройдитесь циклом от 0 до N-1 (ведь нумерация с 0) и, если элементы в заданном столбце идут не в том порядке, в каком должны, поменяйте их местами.

    Код напишите сами. Хотя бы попробуйте.
    Ответ написан
    1 комментарий
  • Функция _kbhit в C++?

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

    Но тут ситуация другая. Майкрософт что-то намудрили cо стандартами и названиями. Чую тут какую-то долгую и запутанную историю полную костылей и заплаток. Я так понял, что _kbhit, это winapi функция, а kbhit - это сишная функция в стандартной библиотеке. Вторая просто вызывает первую. Но нельзя было сделать две функции с одинаковыми названиями, поэтому эти winapi-шные функции оставили с _ в названии.
    Ответ написан
    1 комментарий
  • Почему выражение (-1ll) в ассемблерном коде MSVC равно ff ff ff ff?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Уловка в системе процессорных комманд: 48 c7 45 08 - позволяет загрузить в 64-битную ячейку памяти 32 битное число, автоматически расширяя его до 64 бит.

    Смотрите список кодов x64:
    0x48 - означает, что следующая комманда работает с 64-битами.
    0xC7 - mov immediate (данные в команде)
    Дальше идут флаги, указывающие как интерпретировать аргументы, что куда адресовывать и т.д.

    Но важно, что команда C7 работает с r/m16/32/64 данными, а аргумент у нее может быть только imm16/32 (третий столбец). Т.е. она принимает или 2 или 4 байта, в зависимости от обвеса, а записывать может до 64 бит. Сравните это с коммандой 0xB8 в той же таблице, она уже может принимать 64 бита.

    Если аргумент меньше ячейки памяти, то он расширяется (sign extended) до нужного размера (бит знака копируется влево до упора). Это позволяет записать числено равное значение в более битную ячейку. ведь 32-битное число 0xFFFFFFFF - это -1 в дополнительном бинарном коде, а 0xFFFFFFFFFFFFFFFF - это тоже -1 в дополнительном 64-битном коде.

    Компилятор использует вот эту команду, а не 0xB8, потому что сама команда короче, а исполняется так же быстро. Меньше кода, больше всего помещается в кеш и все работает быстрее, да и exe-шник меньше получается.
    Ответ написан
    2 комментария
  • Правильно ли я понимаю правила arithmetic conversions?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Смотрите документацию. Там действительно утверждается, что int32_t должен иметь размер ровно 32 бита ("exactly").

    Где вы взяли, что int32_t - это псевдоним int?
    Подозреваю, что там, где вы это видели, куча #ifdef и проверок архитектуры.
    Возмножно, на вашей системе, где int итак имеет 32 бита так оно и есть. При компиляции на другую архитектуру внезапно может оказаться, что int32_t - нифига не псевдоним к int.
    Ответ написан
    3 комментария
  • Как рассчитать координаты по известным соседним?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Берете 2 любве точки, пересекаете окружности. 2 получившиеся точки проверяете с остальными n-2 окружностями.
    Ответ написан
    3 комментария
  • Почему tellg() неявно приводится к int при инициализации int, но не может быть сложенным с int?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очевидно, потому что возвращаемый тип имеет определенный оператор преобразования к int или long, но не имеет переопределенного operator+ с int.

    Если смотреть описание возвращаемого типа, то там есть operator+ с каким-то streamoff, а с int - ничего нет. Там, правда, не указано, что есть опретор преобразования к int, так что это, наверно, тоже лучше не использовать.
    Ответ написан
    Комментировать
  • Калькулятор C++ как убрать 1.33333e+06 подобные результаты вычисления?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выводить в фиксированном виде:
    std::cout << std::fixed;  // Меняем формат вывода вещественных чисел 
    std::cout.precision(10);  // Сколько вы там хотите знаков после запятой выводить.
    double e = 1.3333e6;
    std::cout << e;  // 1333300.00000000000;
    Ответ написан
    1 комментарий
  • Returning 'int (*)[(sizetype)(*sizeMas)]' from a function with incompatible return type 'int *' [-Wincompatible-pointer-types] в Си. Что делать?

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

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

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

    Но, да, итерация как бы медленнее будет. Но не на много. В одном случае у вас лишняя адресация, а в другом - умножение. И там и там есть обращение к памяти лишнее, но в векторе векторов - читаются данные из массива указателей, а в плоской структуре - одна и та же длина строк. Ну и данные не так локально в векторе лежат. В целом не стоит эта проблема особого внимания.
    Ответ написан
    4 комментария
  • Почему программа на языке C не выполняется?

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

    Просто догадки:
    У вас опечатка - функция mian вместо main.
    Потом, в конце функции должно стоять return 0;
    Ответ написан
    4 комментария
  • Как убедиться что атомарные операции будут выполнены точно правильно?

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

    В стандартной библиотеке самое близкое к этом - std::condition_variable.

    Платформо зависимое решение может быть эффективнее. Какие-нибудь WaitForSingleObject/CreateEvent в винде, например.
    Ответ написан
    Комментировать
  • Как мониторить изменения буфера обмена?

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

    Рекомендуется использовать Clipboard Format Listener. Надо будет вызвать AddClipboardFormatListener и потом обрабатывать сообщение WM_CLIPBOARDUPDATE. Гуглите эти слова (+ example), и найдете кучу готовых примеров в интернете.
    Ответ написан