Задать вопрос
  • Как создать копию массива значений и массива указателей без std?

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

    Массив указателей от массива значений не отличается ничем. Просто там значения - это указатели. Аккуратно не допустите ошибки при использовании sizeof - если ему передать сам массив (указатель), то это будет размер указателя, а не всего массива. Надо брать размер одного элемента и домножать на их количество.

    Если изначальный объект можно удалить, то вам надо переопределить оператор перемещения, а не копирования. Внутри ваши массивы - это просто указатели и их можно перемещать как переменные:
    keys_ = node.keys_;
    node.keys_ = nullptr;


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

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

    Когда вы определили оператор перемещения (или конструктор перемещения), то далее оберните элемент источник в std::move() при присваивании или передаче в конструктор. Тогда вызовется действительно перемещающий метод.
    Ответ написан
    Комментировать
  • Не выводится отсортирований масив, лезет мусор из памяти, как исправить? run-time check failure #2 - stack around the variable 'c' was corrupted?

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

    Смотрите внимательно, к каким индексам вы обращаетесь и какое значение может принимать переменная j.

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

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

    Копируете в uint64_t. Если надо меньше бит, то можно домножить на большое простое число и потом взять xor младших и старших бит.
    Ответ написан
    4 комментария
  • Задачка по раскрою максимального количества коробок на листе?

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

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

    Она NP-полная - тут нет быстрых и простых решений. В общем случае, возможно только решение полным перебором за N*3^N. Что-то вроде того, что предложил Alexandroppolus, только там вообще не рассматривается случай, что текущее число просто пропускается. Еще можно делать это же без рекурсии на основе битовых масок.

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

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


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

    Во-первых, занумеруйте все клетки. Подойдет простая формула вроде i+m*j

    Вот у вас уже есть n*m вершин в графе. Теперь добавьте ребра. Для каждой клетки (два цикла) посмотрите 4 соседние клетки. Если обе клетки - ., то добавьте из текущей клетки ребро в соседнюю.

    Соседей удобно перебирать, если завести константные массивы для смещений:
    const int dx[4]= {1, 0, -1, 0};
    const int dy[4]= {0, 1, 0, -1};


    Тогда для клетки (i, j) можно перебрать всех соседей одним циклом на 4 итерации - (i+dx[k], j+dy[k]). Надо только не забыть проверить на выход за границы матрицы.

    Ну и вам надо написать функцию типа AddEdge(int u, int v) которая будет в удобную для вас структуру данных добавлять ребра. Граф удобно хранить в виде списков смежности. На C++ это можно сделать просто std::vector<std::vector<int>> и добавлять соседей через vector::push_back. Это на практике работает быстрее всяких связных списков.

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

    А можно вообще граф не строить. Берете ваш алгоритм поиска кратчайшего пути (BFS, Dijkstra или A*) и там везде, где перебираются соседи одной вершины, вставляете код проверки четырех направлений через dx/dy. Вершины можно или нумеровать их координатами, и тогда все массивы пометок будут двумерными, или можно использовать формулу u = i+j*m, (i,j) = (u%m, u/m) для преобразования координат в номер вершины и назад.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выводится ровно то, что вы попросили выводить - неинициализированный элемент массива c.
    Подумайте, чему равно a в конце программы?
    Ответ написан
    6 комментариев
  • Почему возникает ошибка "cannot open file"?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас в input_matrix выход за границы массива: в массиве n-1 элемент, а вы читаете n.

    Массив лежит на стеке, там же где локальная переменная n. Так получилось, что n лежит сразу за matrix (или в пределах восьми байт) и оказывается испорчена. Данные кажутся вам случайными, потому что читаете вы double и какая-то его часть попадает в область памяти int n.
    Ответ написан
  • Есть ли сервис для создания формулы для числа?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Зачем сервис? Вот вам формула для любого числа X = (X-1) + 1. Например, 172 = 171+1.

    Или вам какое-то особое свойство у формулы нужно?
    Ответ написан
  • Не работает код, ошибок нет. Что делать?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы пытаетесь вызвать f1 и т.д., как будто это члены класса A. Но подумайте, какой смысл объявлять члены класса friend? Зачем вообще дружественность нужна? Чтобы иметь доступ к приватным членам класса, но ведь члены класса и так имеют туда доступ. Это бесмыссленная операция.

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

    По идее вы в классе должны их только объявлять (сигнатура без тела), а определение (тело функции) должно быть уже снаружи где-то, как вы с f1 сделали.

    Почему f5 не находится? Попробуйте передать туда, допустим a. Компилятор, внезапно, найдет функцию и ругнется, что не может преобразовать A к int. Но если передать туда int, то компилятор функцию потеряет.

    Тут хитрая магия описанная в стандарте - всякие нагромождения правил посика имен.
    В стандарте сказано, что вот при определении friend функций:
    A name first declared in a friend declaration within a class or class template X becomes a member of the innermost enclosing namespace of X, but is not visible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided - see namespaces for details.


    Я не знаю, как это внятно объяснить, вот просто не работает и все. Стандарт такой. С остальными функциями срабатывает, потому что там в аргументах есть A, поэтому объявления в классе каким-то образом попадают в область поиска имен.

    Просто не надо определять функции-друзей в классе. Это не имеет смысла. Или делайте там статичные функции, или определяйте всю функцию во внешнем пространстве имен а в классе указывайте, что она имеет доступ ко всему классу.
    Ответ написан
    1 комментарий
  • Решение задачи совсем не пойму ее?

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


    А с массивом-то сделать можете?
    Ответ написан
    Комментировать
  • Чем распарсить строку на C?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    sscanf(str, "%d,%d,%d,%d,True", ...);
    Ответ написан
    Комментировать
  • Яндекс.Практикум C++ Что я делаю не так?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вся проверка должна быть query[i] == ' '

    to_string(32) - вернет вам "32" вместо пробела. Тогда уж можно делать (char)32 или static_cast<char>(32). Но ' ' - все равно лучше.

    И еще вы не выводите длину всей строки в конце - ведь там всегда заканчивается слово (может быть пустое).
    Ответ написан
  • C# Math правильно ли я делаю?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Да вроде все правильно. Скорее всего опечатка в задании где-то. Так бывает. Или где-то может быть сказано, что углы должны быть в градусах а не радианах. Тогда выражение под синусом/косиносом надо домножать на 180/pi.
    Ответ написан
    1 комментарий
  • Как равномерно разместить N юнитов на окружности?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    В полярной системе координат их позиции вычислить элементарно: у i-того солдата угол 2pi*i/n и радус фиксированный.

    Для перехода из полярной системы координат в обычную воспользуйтесь тригонометрическими функциями:
    x_i = x_o+cos(alpha_i)*r_i
    y_i = y_o+sin(alpha_i)*r_i
    Ответ написан
    1 комментарий
  • Какой алгоритм лучше использовать для нахождения всех перестановок?

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

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

    Т.е. вам надо найти путь из одной клетки в другую, пройдя по как можно меньшему количеству клеток. Можно ходить в 8 направлений - если пересечь угол, то можно за одну точку на ломаной перейти по диагонали.

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

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

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

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

    Заведите массив флагов длинной с перестановку. Пройдитесь по всем позициям и, если текущая не помечена, запускайте от нее второй цикл, который пометит ее и перейдет в позицию по перестановке (row[i]) и пометит там и опять перейдет и так далее, пока не наткнется на уже помеченную позицию. Так вы побойдете один цикл и пометите все позиции в нем. Поэтому прибавьте 1 к счетчику, когда будете запускать внутренний цикл.

    В решении будет 2 вложенных цикла, внешний - удобнее всего делать for, внутренний можно тоже делать for или while, но в for будет вместо инкримента переход по перестановке. И эти 2 вложенных цикла суммарно обойдут все позиции по одному разу, поэтому время работы алгоритма - линейное.
    Ответ написан
    Комментировать