Задать вопрос
  • Как реализовать обмен сообщениями между программами, где текст сообщения берется из txt-документа?

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

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

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

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

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Как написал Илья, можно растеризовать картинку и подсчитать незакрашенные пиксели. Это простой в реализации метод, но, если нужна высокая точность, он будет очень медленным и требовательным к памяти (экспоненциальное время и память от количества нужных знаков). Однако, есть алгоритм, который позволяет получать площадь в символьном виде (типа 3/2+5113/11*sqrt(31)). Ну, или любое нужное вам количество знаков без огромного потребления памяти или вычислений (метод полиномиален от количества вычисляемых знаков).

    Это некоторое обобщение метода выделения областей или нахождения граней планарного графа.

    Сначала вам надо пересечь все пары окружностей и окружности с прямоугольникм, назначить всем уникальным точкам уникальные номера. Потом надо на каждой окружности составить список всех точек пересечений на ней и отсортировать его вдоль окружности (допустим, против часовой стрелки). Тут же надо добавить самую левую и самую правую точку на окружности (X+-R, Y) - это поможет считать площадь позже. также надо составить список всех точек на прямоугольнике, отсортированных также против часовой стрелки. В этот список надо включить вершины прямоугольника.

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

    Потом сложное - надо отсортировать все ребра в каждой вершине по углу (допустим, против часовой стрелки опять). Для ребер-дуг окружностей надо построить вектор касательной в точке вдоль дуги. Потом сортировать дуги по этим векторам (можно использовать векторное произведение векторов). Если два вектора касательных коллинеарны, то надо сравнивать радиусы окружностей - больший радиус лежит правее, если ребра идут по часовой стрелке, и левее, если ребра идут против часовой стрелки вдоль окружностей. Те, которые идут по часовой всегда лежат правее тех, которые идут проив часовой. При этом ребра вдоль прямоугольника можно считають как дуги окружности бесконечного радиуса.

    После этой сортировки вы в каждой вершине имеете все ребра отсортированные по углу. Теперь можно для каждого исходяжего из вершины ребра найти следующее по часовой стрелке. Это то ребро, которое получится, если стоя в точке пересечения пойти не по этому ребру, а по тому, что идет чуть-чуть левее:
    вот картинка mad paint skillz
    60ae079489dbd754935211.png


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

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

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

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

    Вот так и считается ответ. Все координаты можно считать в символьном виде - они будут вида a/b+sqrt(c)/d. Вектора касательных будут такого же типа. Такие числа можно перемножать, складывать, вычитать и сравнивать. Правда, после операций вы получите множество радикалов, но тут нет проблем, потому что сравнивать результаты вам уже не придется. Ну, или тут можно использовать числа с плавающей запятой и спокойно получить 12-14 знаков точности.
    Ответ написан
    Комментировать
  • Какая ошибка в решении задачи о коммивояжёре методом перебора с возвратом?

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

    Попробуйте переписать с помощью std::next_permutation для перебора всех перестановок. Просто для сравнения и проверки теста - вдруг там опечатка.

    Оно будет работать медленнее рекурсивного перебора из-за отсутствия отсечений, да и одно и то же решение с циклическим сдвигом будет получатся n раз, но для 10 городов должно быстро отработать. Но зато код будет совсем простой: один цикл, как в примере из документации перебирает все перестановки от 0 до n-1. Внутри вы циклом эти числа берете как индексы городов и суммируете расстояния между ними + расстояние между последним до начального. И запоминаете, если сумма меньше известного минимума. Если и там 168 получится - в тесте опечатка.
    Ответ написан
  • Segmentation fault c++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Чему равно n, когда вы заводите массив a[n]?
    Ответ написан
    7 комментариев
  • Как перебрать два массива, и исключить из них дубли, при учете, что дубли могут быть расположены асинхронно?

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

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

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Передайте лямбду, которая вызывает перегруженный оператор вызова у вашей структуры:
    [](const man& item) { item(); }

    Правда, тут не нужно перегружать () для вашего типа, ведь в лямбде вы можете вызвать любой метод или прямо вашу логику реализовать.
    Ответ написан
  • О чем может говорить такая ошибка в подключении через ADOConnection в проекте C++ buildera как исправить?

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Попробуйте сделать вывод в файл. Запускайте с "> output.txt". У меня си работает в несколько раз быстрее (меньше секунды), питон - пару секунд.

    Вывод в консоль тормозит, потому что при компиляции через mingw идет как бы эмуляция линуксовой консоли, которая преобразуется в виндовую. Питон же наверняка работает нативно. Если вы интерпретатор питона из исходников на mingw соберете, то будет работать столько же. В этом примере вы разницу не намеряете, потому что тут вы в основном тестируете скорость вывода в консоль. Замените вывод на вычисления, или что-то другое полезное, и у си будет в разы быстрее питона.
    Ответ написан
  • Как отобразить плоскость на сфере?

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

    Один вариант, сохраняющий углы, но не сохраняющий пропорции - проекция меркатора. Фактически, это циллиндрическая проекция: https://en.wikipedia.org/wiki/Map_projection#Cylin...

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

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

    Далее, если вам так хочется, то ваша задача аггрегирования - NP и кроме полного перебора вы не найдете оптимальное решение. Но вам, похоже, подойдет какое-нибудь достаточно хорошее решение, а не только оптимальное. Тогда будут работать всякие жадности и эвристики. Можно, например, брать самую левую-верхнюю непокрытую клетку и жадно растить вокруг нее максимальный по площади прямоугольник, который не пересекает ни одну покрытую или запрещенную клетку (допустим, перебирая нижнюю и верхнюю границу и жадно раздувая левую и правую до максимума). На примере из вопроса этот алгоритм построит 7 прямоугольников.
    Ответ написан
    3 комментария
  • Проблема с двусвязным списком?

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

    Ошибка в result: вы переписываете значение последнего элемента зачем-то.

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

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

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Рекурсия. Функции передаются 2 каталога. Она сравнивает файлы в них и добавляет новые/пропавшие файлы в списки. Также смотрит на директории. Если какая-то директория новая, то другая рекурсивная функции добавляеет все файлы и каталоги в ней в список новых. Также удаленные директории добавляются в список. Если какая-то директория есть и там и там, то рекурсивно вызывйтесь от них.
    Ответ написан
  • Почему не работают заголовочные файлы?

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

    Каждый cpp файл подключает объявления из остальных "модулей" через include хедеров. Потом каждый "модуль" собирается в объектный файл в котором есть реализации каких-то методов, а каких-то - нет, но они там используются. А потом линковщик собирает все объектные файлы в один исполняемый файл, где все-все-все реализованно.

    Вы же пытаетесь скомпилировать только один модуль сразу в исполняемый файл. Компилятор не находит реализацию класса A (она же в A.cpp. В A.h - только декларация).

    Если в проекте больше одного cpp файла - используйте систему сборки, вроде Cmake (есть и под windows).

    Или если хотите руками - тогда надо сначала собрать все объектные файлы и потом из них исполняемый:
    g++ -c a.cpp -o a.o
    g++ -c main.cpp -o main.o
    g++ a.o main.o -o main.exe
    Ответ написан
    4 комментария
  • Почему не переводит на новую строчку в терминале через uart?Как очистить терминал?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Попробуйте "%i\n" в sprintf передавать.
    Ответ написан
  • Как правильно объявить и заполнить динамический массив указателей на строки?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Скобки вокруг *arr расставьте. И еще, вы зря делаете malloc() для самих строк - вы потом присваеваете адрес строковой константы. Или делайте strcopy, или не выделяйте память под (*arr)[i].
    Ответ написан
  • Как достать видео без водяных знаков из TikTok?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    В худшем случае, водяной знак вкодирован в само видео и без него никак не вытащить. Можно проверить, сохранив видео каким-нибудь расширением "Video Download Helper". А так, надо реверс инженирить сайт.
    Ответ написан
  • Где взять math.h?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно считать экспоненту через ряд тейлора. Правда, тут только e возводится в степень. Если вам надо возводить произвольное число, то надо отдельно считать натуральный логарифм от основания и домножать на него степень. Тоже рядом (смотрите секцию "Вариации и обобщения").
    Ответ написан