Задать вопрос
Ответы пользователя по тегу C++
  • Как можно реализовать данный код без библиотеки string?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Заведите char массивы какой-то достаточной длины. Читайте через gets_s. Сравнивайте строки через strcmp.
    Ответ написан
    Комментировать
  • Как рендерить dx3d11 в dx3d9?

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

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

    CreateThread принимает указатель на функцию. Ей нужен адресс кода, который вы хотите выполнить. И этот самый код должен следовать определенным конвенциям вызова (stdcall). Лямбду к этому не всегда можно привести. Компилятору надо куда-то деть захваченные переменные и как-то их передать в код лямбды. Сами лямбды не обязательно используют те же конвенции вызова, что нужно CreateThread.

    Иногда, если ваша лямбда stateless (не захватывает никаких переменных), то некоторые компиляторы (vs, например) смогут эту лямбду перобразовать к указателю на функцию. Но это не ваш случай, потому что у вас захватываются переменные - вам же надо как-то recoil и mouseManager использовать изнутри лямбды.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это дерево квадрантов (оно же kd-дерево) плохо работает для запроса "найди все точки"), если точки в нем лежат кучно и почти все попадают в ответ. В этом случае вы, как и в наивном решении, проверите почти все точки, но при этом потратите в несколько раз больше времени на накладные расходы - проверку пустых листов и обход дерева.

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

    Вторая оптимизация - если вы видите, что bounding rect текущей вершины лежит целиком в запросе - надо просто вернуть все точки.

    Но есть другая структура, которая будет работать лучше в вашем примере, хоть и занимать в log n больше памяти.

    Вам нужно дерево отрезков бинарных деревьев поиска (можно использовать std::set).
    Заведите дерево отрезков по OX, где каждая вершина будет упорядоченное по OY set всех точек попадающих в данный отрезок по X.

    При запросе вы разбиваете отрезок по X запроса на Log n отрезков-вершин в дереве отрезков (это те вершыны, которые надо взять в запрос по ссылке выше) Далее в каждом из этих Logn сетов можно через lower_boundary и upper_boundary получить итераторы начала и конца всех точек в вашем запросе.

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

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

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

    Еще один бонус этой структуры, что можно быстро удалять/добавлять/менять точки и все остается балансированным. Но, в отличии от kd-дерева, оно занимает в log n раз больше памяти и операция поиска всегда занимает O(log n + ответ), что может быть чуть медленее лучшего случая kd дерева, где вы можете сразу же закончить поиск, если очевидно, что в ответе ничего нет. Зато в худшем случае будет работать быстрее.
    Ответ написан
    Комментировать
  • Найти номер первого и последнего вхождения элемента в масссив?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Что у вас там за цикл по k после вызова бинприска? Именно он и тормозит делая вашу программу работать за nm вместо m log n.

    И да - используйте lower_bound и upper_bound. Это в точности то, что вам нужно.
    Ответ написан
    Комментировать
  • Как удалить поддерево полностью?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    node = nullptr;

    Этот код переписывает значение указателя node, который является аргументом функции, переданным по значению. Фактически, вы затираете локальную переменную.

    Кроме того, ваша функция пытается переписать все указатели нулями, но нигде не делает delete - поэтому там у вас утечка памяти.
    Ответ написан
  • Как организовать такую запись с помощью класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    System - это глобальный экземпляр класса, который содержит член out, у которого есть метод println.
    class SystemType {
    public:
      class Out {
          public: void println() {
              cout << "haha";
          }   
      } out;
    } System;
    Ответ написан
    Комментировать
  • Найти количество чисел меньше заданного?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Куча ошибок. Вы читаете запросы в массив B и больше нигде не используете. Конструкция A{m<i] вообще удивительна. Массив надо отсортировать.
    Ответ написан
  • Почему операция 0.0 / 0.0 выдает ошибку?

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

    If the second operand is zero, the behavior is undefined,


    Правда, есть одно исключение:
    except that if floating-point division is taking place and the type supports IEEE floating-point arithmetic


    Вот только этот стандарт IEEE 754 не постулируется стандартом C++ (потому что зависит от аппаратной реализации чисел с плавающей запятой).

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

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

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

    Быстро получать наибольший общий делитель можно за логарифм с помощью структуры данных дерево отрезков. Общая сложность будет O(n log n).

    Второе решение такое: Раз числа на отрезке все делятся на что-то больше 1, то все они делятся на какое-то простое число. Значит задача состоит в том, чтобы найти самый длинный отрезок из чисел, делящихся на одно и тоже простое число. Значит вам надо разложить каждое число в массиве на простые множители и работать с ними отдельно. Далее, вам достаточно просто хранить для каждого простого множителя, какая длина у самого последнего отрезка из чисел с этим делителем и на какой позиции он закончился. Когда вы нашли, что текущее число делится на p, вам надо или начать новый отрезок или добавить текущую позицию к последнему отрезку.

    Общая сложность у этого решения будет O(n sqrt(a)), но его можно ускорить, если предподсчитать для каждого числа от 1 до A один из его простых делителей.
    Ответ написан
    3 комментария
  • Как удалить елемент из очереди с приоритетом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очередь с приоритетом реализуется на основе кучи или бинарного дерева поиска (set). В первом случае удаление делается так: Меняете местами первый и последний элемент в куче. Удаляете последний. Потом просеиваете первый элемент вниз, чтобы он встал на свое место. Во втором случае надо просто удалить из сета элемент begin().
    Ответ написан
  • Как решить ошибку нарушение прав доступа при чтении по адресу?

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

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

    Поскольку n^n делится на a, то n делится на все простые делители a. Поэтому надо разложить a на множители (пусть a= p1^k1*p2^k2 ...)

    Тогда n надо искать в виде k*p1*p2*...

    Это самое k надо перебрать от 1 до максимального ki и проверить, что n^n делится на a. Для этого надо подсчитать, сколько раз k делится на p_i (пусть - это q_i). Тогда надо проверить что, (q_i+1)*n >= k_i для всех простых делителей p_i.
    Ответ написан
  • Как плавно изменять целое число в течение некоторого времени от одного значения до другого?

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

    Или считайте по формуле ans = from + (to-from+0.0)*time/duration
    Ответ написан
    Комментировать
  • Найдите сумму и количество делителей натурального числа?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В с++ разве есть оператор and? Попробуйте заменить sqrt на проверку i*i ==n. Видимо, проблемы с точностью. Плюс может быть переполнение. Сумма должна быть long long.
    Ответ написан
    1 комментарий
  • Почему выдает что переменные x,y,z - неинициализированы? Почему выдает что == неуместны и возможно я имел ввиду =?

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

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

    Вам нужно создать прозрачное окно и рисовать в него то, что идет поверх рабочего стола (гуглите "winapi draw in transparent window").

    Чтобы не рисовать поверх каких-то окон - надо в каком-то битмапе нарисовать черным цветом силуэты всех этих окон (надо все окна в системе перебрать - тут вам помогут всякие всякие GetWindowRect, EnumWindows, IsWindowVisible.). И при проприсовке надо этот битмап брать как маску (гуглите "winapi clip region").

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас цикл на 10 итераций (for (int count=0; count < 10; ++count)). С возможным ранним выходом (break).
    Ответ написан
    Комментировать
  • Для чего объявляется вложенная структура (или класс) перед тем, как она объявляется дружественной?

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

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

    Но откуда тут вообще может быть непонимание? В C++ никогда нельзя менять, на что ссылаются ссылки. const/не const может быть только то, на что оно ссылается.

    Edit: изначально я тут некорректно назвал это константной ссылкой, но по хорошему, оно называется ссылка на константу.
    Ответ написан
    4 комментария