Ответы пользователя по тегу C++
  • Как из убывающей последовательности сделать возрастающую в c++?

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

    2) Разворачиваете каждую их них.

    3) ???

    4) PROFIT!

    Вот вам подсказка, как можно выделять в массиве убывающие последовательности.
    start = 0;
    while (start < n) {
      end = start;
      ПОКА (start..end+1 - убывающая последовательность) {
        ++end;
      }
      // start..end - убывающая последовательность.
      start = end+1;
    }


    Развернуть кусок с i по j можно одним циклом while. Меняйте местами 2 крайних элемента и тогда останется развернуть кусок с i+1 по j-1.
    Ответ написан
    Комментировать
  • Можете помочь применить lower_bound и upper_bound в С++?

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

    надо ускорить программу с помощью lower_bound и upper_bound,


    Ну вот посмотрите на эти самые lower_bound и upper_bound в документации. Они как раз находят первое и за-последним включение заданного числа, если оно в упорядоченном массиве встречается. Если числа там нет, то они оба будут указывать на первое большее заданного число.

    Функции возвращают итераторы. Чтобы преобразовать их в индексы, можно воспользоваться std::distance, чтобы узнать расстояние до начала массива. Там по ссылкам выше прямо примеры есть, которые все это делают.
    Ответ написан
  • Как реализовать функцию копирования бит со смещениями в src и/или dst и не кратным 8 количестве бит?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Самое эффективное - использовать какой-нибудь SSE (гуглите shift bits sse. Лучше всего, мне кажется, подойдет _mm_slli_epi64). Но там очень много кода и случаев будет. Придется отдельно разбирать случаи сдвига влево и вправо, отдельно вычленять биты, которые SSE операция при сдвиге бы потеряла и записывать куда надо.

    Следующий по эффективности вариант - это читать в int64_t, и там сдвигать биты. Придется сначала из переменной доставать старшые/младшие 1-7 бит и писать их отдельно, потом сдвигать биты и записывать куда надо. Используйте memcopy для чтения/записи 64-ех бит. Еще можно ускорить, если отдельно обработать первые несколько байт до 64-битного выравнивания, и потом придется еще обрабоать отдельно лишние 0-7 байтов в конце, если их количество не делится на 8.
    Ответ написан
  • Как зашифровать алгоритм внутри программы?

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

    Вы можете только усложнить реверс инжениринг. Самый эффективный способ, если не очень важна производительность, то можно реализовать собственную виртуальную машину с кучей похожих, но немного разных инструкций, и реализовывать алгоритм на ней. Надо еще впихнуть в алгоритм всяких неважных действий, типа тут прибавить 5 к числу, оно потом в алгоритме умножается на 2, потом вычесть 8 и 2. Можно написать транслятор с простого скриптового языка на ЭТО, иначе вы и сами запутаетесь.

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

    Тут та же проблема, с которой копирасты пытаются бороться: алгоритм - это информация. И если он, таки, исполняется на компьютере пользователя вы никак не можете ему запретить его смотреть, копировать или модифицировать.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Перебирайте буквы от младших к старшим: a,k, d,b,z, e...

    Проверяйте правильность суммы поциферно справа на-лево как можно раньше.

    Т.е. после перебора a уже можно проверить, что (a+a+a) % 10 = a. Потом, после k надо проверить (ka+ka+ka)%100 = ka, после dbz можно проверить третью цифру.

    Можно немного соптимизировтаь, есл ине считать (ка+ка+ка)%100, а помнить, какой там перенос из младшей цифры и проверять уже только (k+k+k+carry1)%10 = k, carry2 = (k+k+k+carry1)/10; Потом проверить, что (d+b+p + carry2)%10 = z и т.д.

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

    Следующее улучшение - не перебирать буквы s, z, e и r, а сразу считать, какими они должны быть, чтобы сумма сходилась. С s и z все тривиально, а для e и r надо чуть-чуть математики.

    Это надо аккуратно выписать уравнения вида (e+a+e+carry2)%10=a.

    Тут надо применить свойства модуля: 2e %10=-carry2 % 10, Тут для e есть 2 решения, если carry2 четно: (10-carry2)/2, (20-carry2) / 2

    Но это улучшение не сильно ускорит.
    Ответ написан
  • Что значит эта ошибка?

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Видимо, надо вывести все пары n и k, таких что k^2+n^2=n!/(k!(n-k)!), a <= k <= n <= b.
    Ответ написан
    Комментировать
  • В чём ошибка кода?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    if (!((ceil(y)) % 2 && ...

    Поставьте скобки вокруг ... % 2

    Приоритет операций такой, что сначала вычислится 2 && ... и потом вы на этот bool попытаетесь поделить с остатком.

    И вообще, ваш код невозможно читать. Слишком много скобок. Во-первых, введите 4 переменные и посчитайте в них floor/ceil от x/y. Удалите очевидно лишние скобки.

    Потом вместо !(a%2) лучше писать (a % 2 == 0), а то с вашим количеством скобок вообще непонятно, к чему ! относится.
    Ответ написан
    5 комментариев
  • Как найти принадлежность точки к закрашенной области на плоскости?

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

    Далее, фигура повторяется блоками 2x2, т.е. вам не важны сами координаты, а только их положение в блоке.

    Для высчитывания координаты в блоке можно или вычитать 2, пока координата больше 2, или вычесть из x (floor(x) - floor(x)%2). floor(x) даст целые числа. Потом надо это число сделать четным, возможно вычесть 1. floor(x)%2 - как раз и даст нам, что надо вычесть.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Разбейте область на простые фигуры (квадраты, окружности, полуплоскости) и опишите логически. Вроде точка в области, если она в фигуре А, но не фигуре Б; или в фигурах В и Г, или в фигурах Д и Е.

    Далее перевести это в код - это один if с кучей условий объедененных логическими или (||) или логическими И (&&).
    Ответ написан
    Комментировать
  • Ошибка сегментирования (стек памяти сброшен на диск) c++. Как исправить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ваша программа бесконечно уходит в рекурсию, у нее кончаетсся память и она падает. func(1, v) в цикле при i=0 вызовет func(1,v1), которая опять же вызовет func(1,v1), которая опять же... И так пока программе не поплохеет.
    Ответ написан
    Комментировать
  • Как решить эту задачу на C++?

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

    Это также можно доказать. Брать более одной 100 нет смысла, их можно было бы заменть на 200. Также более двух 200 брать смысла нет - три можно разменять на 500+100, что меньше купюр. Аналогично для всех оставшихся купюр.

    Ну вот вам осталось для каждой купюры проверить, что оставшаяся сумма не меньше купюры, потом выдать сколько влезает купюр и заменить сумму на остаток от деления.
    Ответ написан
    2 комментария
  • Как отправить файл на почту?

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


    Если вы в линуксе, то введите в терминале "man sendmail". Разберитесь с командой и вызывайте ее из C++ программы через system.

    Иначе - разбирайтесь с сокетами, протокалами SMTP, TCP. Простенький клиент строчек на 3000 сможете написать через пару месяцев, наверное. Ну, или, все-таки, пересмотрите ваши условия и используйте библиотеки или более удобный для этого язык. Так в питоне это делается буквально в 2 строчки.
    Ответ написан
    Комментировать
  • Где ошибка в решении?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас number в int не помещается. А вы цикл гоните от 2 до number. У вас условие i < number в цикле будет всегда выполнятся - потому что ну не может int i быть больше number.

    edit: И вообще логика проверки на простоту у вас сломана. del = i выполнится для любого j, такого что i на него не делится. Т.е. если i=6, то при j=5 вы dеl перезапишите. Вам надо в цикле устанавливать bool flag. И, после цикла на него смотреть.
    Ответ написан
    9 комментариев
  • Почему максимальный размер объекта std::string равен 4611686018427387897?

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

    Это 2^62-7. Почему 2^62? Может, в силу каких-то причин в вашей системе нельзя адресовать больше 62 бит. Может, система 2 бита для чего-то использует. Почему -7? Надо еще где-то хранить длину, надо оставить место для нулевого символа в конце и надо оставить нетронутым индекс std::string::npos - это значение используется для обозначения "несуществующего индекса". Конкретное значение зависит от того, что там программисты стандартной библиотеки сделали.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Запустите и посмотрите: https://www.onlinegdb.com/online_c++_compiler. Попробуйте поменять по одному символу и смотреть, что происходит с выводом. Так вы поймете, что именно выводится, а потом чуть чуть знания C и вы поймете, почему так происходит.
    Ответ написан
    4 комментария
  • Не работает алгоритм std find для строки?

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

    Для того, что вам надо - есть std::string::find. Т.е. вам надо вызвать str.find(" ").

    Или же ищите один символ. Только не забудьте algorithm включить, а то непонятные ошибки с итераторами полезут.
    Ответ написан
    1 комментарий
  • Не понимаю, как правильно реализовать программу?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Во-первых, можно отлично читать из файла сразу число. Вы как с консоли числа вводите? Вот точно также, только из файла. Вы как строку-то читаете? Вот передавайте там не строку, а int условный. Ну, еще, если scanf-ом читаете, то надо туда %d вместо %s передавать. А так есть еще функции преобразования числа в строку. Читайте справки по atoi, sscanf, stringstream.
    Ответ написан
    3 комментария
  • Алгоритм для нахождения количества пересечений отрезков в последовательности(списке)?

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

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

    Это если вам надо весь массив, как в примере, выводить. Не знаю специфику вашей задачи, может эффективнее будет класть в массив пары {координата, +-1} и сортировать. Потом точно также обойти слева направо поддерживая счетчик.
    Ответ написан
    4 комментария
  • Инициализирование класса?

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

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

    Если бы в объекте был еще и конструктор, то первый и второй варинт были бы идентичными.

    Третий вариант всегда инициализирует объект и выделяет память, поэтому он будет медленнее.
    Ответ написан
    Комментировать