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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вообще, работу с указателем на base тоже надо переписать через memcpy. Потому что это UB. Вдруг выравнивание у массива не такое, как у структуры Base. Без memcpy тут никак. Другого способа разместить 2 структуры в памяти подряд компактно - нет.

    Edit: конечно, можно объявить вашу стоуктуру где поля base и S1 идут рядом, но там будет какой-то padding. Работать с этим как с сериализированным массивом байт - нельзя.
    Ответ написан
    1 комментарий
  • Задача о рюкзаке, используя 1-D массив?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Вы не правы. Двумерный массив считает, можно ли набрать вес i используя первые j предметов. А не j-ый предмет.
    Далее, обычно можно сэкономить память храня и пересчитывая только одну строку этого массива, но ДП все еще остается двумерным. Также числа Фибоначчи можно считать храня лишь 2 последних числа, но на самом деле там массив на n элементов в дп.

    Этот трюк не всегда возможен. Например, если вам надо не только максимальный вес/цену найти, а еще и набор предметов. Восстановление ответа не всегда можно сделать лишь по последней строке.
    Ответ написан
  • Как найти расстояние от точки до вектора?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Есть костыль:
    #define Class3 Class3_Unused
    #include "module1.h"
    #undef Class3


    Таким побразом при включении module1.h вместо Class3 будет объявлятся какая-то хрень, которую нигде вы использовать не будете.

    Правда, все ломается, если у вас этот module1.h включен по цепочке других инклудов. Надо аккуратно в каждом месте, где вы его включаете так же обарачивать в define.

    Но по уму, это большой косяк авторов module1 и module2, что они не используют namespace. Их надо бы переписать.
    Ответ написан
    1 комментарий
  • Как сделать расчёт пройденного расстояния лучом?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Формула: W/sin(a). Ну, или косинус, в зависимости от того, что вы за угол задаете. W - ширина прямоугольника.

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

    Формула осмысленна: если нет отражений, она очевидна. Чем вертикальнее луч, тем больше ответ.

    Формула меняется для любой отправной точки: надо лишь опять нарисовать решетку из прямоугольников. Видимо, там будет не W, а оставшаяся ширина от начала до правой стенки.
    Ответ написан
    6 комментариев
  • Как ускорить аудио под необходимый длину?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    727/x. Для 720 получается 1.0097222222...
    Но вообще, если это аудио, то можно паузы попробовать повырезать в какомнибудь audacity руками.
    Ответ написан
    Комментировать
  • Как решить подобную задачу?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ошибка, если интересно, в том, что в коде написан & вместо %. Соответственно, пропускаются не числа, которые не делят n, а числа, дающие не 0 в побитовом И с n.

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

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

    Совсем быстрое решение - это динамическое программирование по бинарным цифрам корня. Это весьма сложный алгоритм. Сработает, в общем-то, для n до 2^64. Считайте F(l,f) - количество способов как-то расставить первые l бит числа, т.ч. все биты, единичные в n, взяты по 0, и число не превосходит корня из n, а f - флаг, означающий, что число уже строго меньше корня.

    Легче считать это циклом снизу вврех. Смотрите, какую цифру можно дописать к (l,f): если в n стоит 1 в этом бите - то только 0. Иначе, можно дописать 1, только если f=1 или в sqrt(n) стоит 1 в этом бите. Новый флаг f' будет 1, только если f=1, или вы поставили 0, а в sqrt(n) стоит 1.

    Потом ответ надо домножить на 2 и вычесть 1, если (int)sqrt(n) & n == 0.
    Ответ написан
    1 комментарий
  • Как убрать дублирование чисел в бинарном файле на си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    С чего вы взяли, что туда записывается два числа 7?
    Туда записывается одно число размером в 4 байта, которое, если его интерпретировать как строку, выглядит как "7 7 ".

    Вы числа читаете и пишите в бинарном формате. Соответственно, файл input.bin у вас должен в hex редакторе выглядеть "0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x07...", а не то, что у вас.
    Ответ написан
  • Как найти наикратчайшие пути взвешенного орграфа, представленного матрицей инцидентности, используя алгоритм Дейкстры?

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

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

    Кстати, у вас матрица инцидентности неправильная: должно быть по 2 числа в каждой строке. Обычно ставят -цену у начальной вершины и +цену у конечной.
    Ответ написан
    4 комментария
  • В чем разница записи массива через указатели?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что * выполняется перед вычетанием. *(current-1) - это предыдущий элемент. (*current-1) в плохой версии - это текущее значение минус 1.
    Ответ написан
    Комментировать
  • Как преобразовать char* содержащий символы unicode?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам надо \uXXXX преобразовать в char16_t? Можно это руками делать. Берете по 6 байт из строки. Последние 4 руками преобразуете из 16ричной системы. Если символ от a до f, то прибавляете к нему 10-'a'. Если от 0 до 9 - 0-'0'.

    Удобно это циклом делать, сдвигая ответ на 4 бита влево и прибавляя новый символ:
    std::wstring Parse(const std::string encoded) {
      std::wstring result;
      for (int start = 0; start < encoded.length(); start += 6) {
        if (encoded[start] != '\\' || encoded[start+1] != 'u') return result // строка неправильного формата.
        char16_t nxt = 0;
        for (int i = start +2; i < start+6; ++i) {
          int cur = 0;
          char &chr = encoded[i];
          if ('0' <= chr && chr <= '9') cur = chr - '0';
          if ('a' <= chr && chr <= 'f') cur = chr - 'a' + 10;
          if ('A' <= chr && chr <= 'F') cur = chr - 'A' + 10;
          nxt = (nxt << 4) + cur;
        }
        result += nxt;
      }
      return result;
    }
    Ответ написан
  • Как можно улучшить код?

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


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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очень многие числа нельзя записать в виде числа с плавающей запятой, потому что они не представимы в виде доичной дроби с заданным количеством знаков. Например вы 1/3 как десятичную дробь не запишите. Ибо там 0.3333... - бесконечная последовательность троек. Для хранения double выделенно сколько-то бит под мантиссу, но их сильно меньше бесконечности.
    Поэтому ни 1/10, ни 3/100, ни 1467/1000 и почти любая дробь будет непредставима в виде float. Поэтому, если вам нужна точность, то вы округляете до целого и храните количество, скажем, тысячных долей в целых числах. Как сумму денег вы храните не долларах, округленных до 2 знаков, а как целое число центов.
    Ответ написан
    Комментировать
  • В чем проблема в коде работы с графом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ошибка в том, что у вас граф криво задан. У вас там ровно 6 списков. А размер графа - 7. Поэтому в MakeStep вы обращаетесь к graph[6], а это undefined behavior. А там непонятно, что происходит. Может вы таблицу портите каким-то значениями и никогда положительного значения не получаете. Скорее всего корраптите память через обращение к мусорным adj в std::array (который на стеке лежит) и получаете мусор в каких-то локальных переменных.
    Ответ написан
  • Компиляция C++ кода на Ubuntu и Windows даёт мне разный результат, почему?

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

    Советую переписать код. Возвращайте std::array<std::bitset<16>,4> например. Вместо push_back сразу обращайтесь к i-ому элементу ответа.

    Далее, у вас там 2 функции делают одно и то же - разбивают большой bitset на несколько маленьких. Напишите template функцию, которая выделяет из битсета длиной N битсет длиной M со сдвигом offset. Внутри просто циклом присваивайте res[i] = input[i+offset].

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

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

    Т.е. действительно, в вашем случае надо в AIJH добавить точки ABKJH.

    Образуются ребра длины 0 - значит повторяющиеся вершины надо просто выкинуть.
    Ответ написан
    Комментировать
  • Как решить данную задачу на двумерные массивы c++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    int sum = 0;
    int cnt = 0;
    for (int dx = -1; dx <= 1; ++dx) {
      for (int dy = -1; dy <= 1; ++dy) {
        if (dx == 0 && dy == 0) continue;
        int nx = i + dx;
        int ny = j + dy;
        if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
        sum += A[nx][ny];
        ++cnt;
      }
    }
    B[i][j] = cnt == 0 ? 0 : sum / cnt;
    Ответ написан
    Комментировать
  • Что не так с кодом, проверяющим логическую схему?

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

    Во-вторых, у вас ошибка с тем, что вы из bitmask берете биты, которые есть числа 0 и 1 и проводите над ними битовые операции, а не логические. И это у вас там 32-битные числа же! Для | и & оно еще совпадает с вашими ожиданиями, а вот ~ обращает ВСЕ 32 бита числа.

    Поэтому ~(bitset[E] | bOrD) всегда выдаст или -1 или -2. Вы потом это пропустите через or, получите опять же -1 или -2 и в конце преобразуете это в bool. И вот тут-то оно всегда и станет true.

    Чтобы это исправить, или используйте логические операции (||, &&, !), или вместо ~x используйте x^1, или в самом конце возвращайте результат с &1, чтобы значения остальных бит ни на что не влияли.
    Ответ написан
    5 комментариев
  • Правильно ли понимаю работу ссылок в С++?

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