Задать вопрос
  • Как поменять порядок битов в байте C?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Вручную, наивно. Представьте, что это массив из 8 значений. У вас есть операции "прочитать i-ое значение" ((x >> i) & 1) и "записать значение a в позицию i" ((x & ~(1 << i)) | (a << i)). Дальше остается написать цикл и руками менять биты местами.

    Дальше, конечно, можно извращаться с оптимизацией и всякмими битовыми хитростями.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это получается не переопределение, а просто метод у другого типа с таким же названием. Изначальный метод все еще можно вызвать у объекта класса (если привести тип). Также изначальный меотд доступен внутри класса потомка.

    Суть переопределения в том, что это ПЕРЕопределение. Замена одной функциональности на другую. Без virtual этого не происходит.

    Можно же объявить функцию fn у двух совсем не связанных классов, вызвать ее у двух экземпляров и увидеть разный результат, правда? Но тут нет никакого переопределения. Концептуально у вас тут то же самое.
    Ответ написан
    7 комментариев
  • Необходимо получить RGB цвет пикселя который находится на кординатах x и y?

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

    Затем пользуясь image из модуля Pillow можно получить конкретный пиксель.

    В этом же pyautogui можно симулировать клики мышью. Читайте документацию.
    Ответ написан
    Комментировать
  • Как найти сумму элементов массива, находящихся на нечётных позициях?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Код выглядит правильно, только массив объявлен на 15 элементов, а цикл до 16 идет. И, возможно, надо 0 на 1 в проверке поменять. "Нечетные позиции", по человечески - это первая, третье и т.д. Но им соответствуют четные индексы 0, 2...

    Edit: А еще в коде стоит точка с запятой после for, из-за чего цикл оказывается пустым, а вводится только один элемент (и тот за границей массива):
    for (i=0; i<16; i++); // <----------
    scanf("%d", &A[i]);
    Ответ написан
  • Как выделить память в другой функции, передавая pointer через аргументы?

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

    Если уж очень надо через аргументы, то передавайте указатель на указатель:
    static void update_callback(char **ptr)
    {
        *ptr = (char *)malloc(sizeof(char) * TEST_STR_SIZE + 1);
    ...


    P.s. В вашем коде утечка памяти. Вы выделяете память, потом единственный указатель на эту память переписываете указателем на TEST_STR.
    Ответ написан
    6 комментариев
  • Как вернуть несколько значений из функции?

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

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

    У вас опять куча мелких ошибок в коде.

    На вскидку:
    f надо уменьшать там, где у вас закомментированно, после ввода. А то вы после основного цикла обращаетесь по индексу не уменьшенного f и выходите за границу массива.

    Массив p надо переписывать только при удачной релаксации, вы же в основном цикле, после вызова функции еще зачем-то всегда переписываете предка. Из-за этого у вас там полный бред в массиве ссылок к предку получается и цикл вывода, скорее всего, виснет в бесконечном цикле из ссылок.
    Ответ написан
  • Как не обрезать стркоу после \0?

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

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

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

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

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

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

    Пусть ставшиеся числа 1,2,3,4. Сначала вы ставите на первую позицию 1 (оставляете все как есть).
    Потом вы должны получить в массиве 2,1,3,4 и запуститься рекурсивно. Это один swap.
    Потом надо получить в массиве 3,1,2,4. Это можно сделать одним swap из предыдущего состояния.
    Важно тут, что вы не возвращаете массив назад после каждого рекурсивного вызова. Иначе вам пришлось бы делать циклический сдвиг части массива на каждой итерации (1,2,3,4 -> 3,1,2,4).

    В конце, после последнего рекурсивного вызова у вас будет 4,1,2,3. Чтобы вернуть все как было вам придется после цикла с рекурсивными вызовами сделать циклический сдвиг массива влево на 1 позицию.

    Т.е. рекурсивные вызовы будут как-то так:
    perm( arr, size, index + 1 );
    for( i = index + 1; i < size; i++ )
    {
        swap( arr[i], arr[index] );
        perm( arr, size, index + 1 );
    }
    int tmp = arr[index];
    for (i = index; i < size-1; i++)
        arr[i] = arr[i+1];
    arr[size-1] = tmp;
    Ответ написан
  • Почему возникает ошибка 'std::out_of_range'?

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

    Скорее всего, это происходит на строчке:
    result = num.at(0);
    Ответ написан
    Комментировать
  • А как предков вывести?

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

    В очередь вы должны класть только идентификатор вершины/состояния. В той задаче это были 2 координаты клетки поля. Тут - это четырехзначное число.

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

    Еще раз, в очереди у вас только число, а в массиве рядом пометки о песещении и путь к предку (расстояние конкретно в этой задаче считать и выводить не нужно).

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

    В конце надо циклом while от конечной вершины по сохраненным предкам идти, пока не упретесь в начало. Потом список обойденных чисел надо развернуть. Или хитрость - проводите обратные операции начиная с конечного состояния, пока не найдете начальное. Операции развернуть просто - вычитайте из первой цифры и прибавляйте к последней. Сдвиги симметричны и остаются как есть. Тогда не надо разворачивать ответ после восстановления циклом while.
    Ответ написан
    Комментировать
  • А конь по кругу ходит?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Что-то не то с bfs. Вместо set visited надо иметь двумерный массив, в котором надо считать расстояния. Значение оттуда же и возвращать. Еще плохой код в том что локальные x1, y1 имеют те же имена, что и аргументы функции.
    Ответ написан
  • Почему в С++ появляется Segmentation fault?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    q.push(make_pair(x,y));
    // или эффективнее.
    q.emplace(x,y);
    Ответ написан
    3 комментария
  • Как правильно решить задачу, используя формулу комбинаторики?

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

    Тут вообще-то ответ - числа фиббоначи. Подумайте, почему.
    Ответ написан
    Комментировать
  • Как разбить строку в Си на части?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Обычно можно, но с оговорками. Csv может быть урезан. Например там только текст, а оригинальный формат ещё и шрифт размечал.

    Но эти потерянные вещи можно придумывать по ходу на какие-то стандартные значения.

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

    Плохо, если там какое-то самопальное сжатие или обфускация, тогда взглядом на файл формат не расковырять.
    Ответ написан
    2 комментария
  • Проблема с преобразование с char в int?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    В питоне большие целые числа встроенные. Но только целые.
    Если вы хотите соранить всю точность, то вам нельзя использовать числа с плавающей точкой. В вашем коде у вас деление на 100, которое и приводит к преобразованию в float и потерю точности. Замените деление на целочисленное и ответ будет точным.

    i - i * p // 100 посчитает точно, но там окргуление при делении будет вниз. Чтобы округлить вверх, можно воспользоваться хитростью - прибавть в числитель знаменатель -1: (i * p + 99) // 100 округлит вверх.
    Ответ написан
    Комментировать