• Как решить олимпиадную задачу python?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Тут есть 2 подхода - дихотомия (бинарный поиск) по ответу, как написал Василий Банников: Вы бинарным поиском ищите значение r. Для каждого значения проверяете, а связен ли граф всех антен через обход в глубину (ребро межу двумя антеннами, если они видят друг друга напрямую для данного r).

    Другой вариант - через алгоритм построения остовного дерева Краскала. Сортируете все возможные ребра в графе (все расстояния между парами вершин). Потом добавляйте в изначально пустой граф ребра в этом порядке, пока он не станет связен (пока не построите остовное дерево). Последнее добавленное ребро и будет задавать r (половина длины ребра - ответ).
    Ответ написан
    Комментировать
  • После закрытия скомпилированной программы появляется ошибка Debug Assertion Failed?

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

    Вижу как минимум одно такое место. delete_reload_virus иногда удаляет virus, а потом что-то делает с r_vir. Но в качестве аргумента ей из viruspodMoving передается этот же самый r_vir.

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

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

    Клиент после отсылки данных должен из сокета читать ответ.
    Ответ написан
    Комментировать
  • Код не успевает выполниться.С++.Что делать?

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

    Можно поиск символов перевода строки ускорить всякими SIMD инструкциями.

    Но вообще, у вас файл маленький, не должно быть проблем со скоростью.
    Ответ написан
    Комментировать
  • U% не работает. Почему ответ всегда ноль?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Что-то неправильно запускаете. Скопировал код, запустил: выдало 9.
    Ответ написан
  • Есть ли в C++ функция преобразующая текст в байты и байты в текст по заданной кодировке?

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

    С помощью его можно читать файлы в utf_8, например, так:
    std::ifstream f("file.txt");
    std::wbuffer_convert<std::codecvt_utf8<wchar_t>> conv(f.rdbuf());
    std::wistream wf(&conv);


    Потом читаете из wistream, как будто это обычный cin. Только вместо char нужен wchar_t, а вместо string - wstring.
    Ответ написан
    3 комментария
  • Где у меня ошибка при выводе порядковых номеров?

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

    И еще, похоже вы отдельно считаете цифры и четные номера, а в задаче похоже надо считать сколько символов удовелтворяют обоим условиям. Для этого надо воспользоваться логической операцией И (&&) в условии if.
    Ответ написан
  • Почему неправильно считывается строка?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    file.get() читает один символ, возвращает его и переходит к следующему символу ввода. Поэтому код:
    while (file.get() != ']')
    {
       temp += file.get();
    }


    читает первый символ, сравнивает со скобкой, потом приписывает в temp второй символ. Потом читает третий и, возможно, приписывает четвертый и т.д. Два вызова file.get() выполняют два чтения.

    Правильно делать так:

    while ( (с = file.get()) != ']')
    {
       temp += с;
    }


    И похожим образом обрабатывайте '[' перед этим. Читайте в переменную, сравнивайте и не забудьте прочтенный символ засунуть в строку.

    Ну, или используйте в условиях istream::peek.
    Ответ написан
    Комментировать
  • Должны ли разработчики понимать абсолютно весь проект?

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

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

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

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

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

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

    Но это все равно будет работать за экспоненциальную сложность.

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

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

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

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

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

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

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

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

    С матрицами все тоже самое, но вместо ввода одного числа надо читать NxM чисел (очевидно, двумя циклами). Вместо одной переменной суммы у вас будет матрица, к которой вы двумя циклами будете прибавлять. Можно написать функции ReadMatrix, AddMatrix, может так понятнее будет.

    Да, вам нужен внешний цикл до k. Внутри он будет вводить матрицу и прибавлять ее в матрицу-сумму.
    Ответ написан
    Комментировать
  • Можно ли определить тип переменной в удобном виде?

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

    Эти заковыристые имена создает компилятор. Если заставить его это не делать, то все сломается. Поэтому, кажется, вы всегда будете получать вот такие вот странные имена. Но их можно расшифровать назад (или вот).
    Ответ написан
    2 комментария
  • Как здесь распараллелили задачу?

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

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

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

    Если вы будете игнорировать точки уже на выпуклой оболочке, то все оставшиеся точки будут лежать в одной полуплоскости относительно данной. А дальше надо выбирать точку, вектор на которую правее. А если вектора коллиниарны - то ближайшую (или самую далекую, если точки на границе выпуклой оболочки вы хотите пропустить.

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

    Вот набросок кода на C++, думайте, что это псевдокод.

    vector<int> ConvexHull(vector<double> x, vector<double> y) {
      int first = ...; // Тут поиск самой нижней-левой точки.
      const int n = x.size();
      int cur = first;
      vector<int> ans{first};
      // Текущий вектор стороны может идти вправо от самой нижней точки.
      double side_x = 1;
      double side_y = 0;
      while (true) { 
        int bsti = -1;
        // Вектор на лучшую точку.
        double bst_x = 0;
        double bst_y = 0;
        // Расстояние до нее.
        double bst_dist = 0;
        for (i = 0; i < n; ++i) {
          if (i == cur) continue;
          // Вектор на текущую точку.
          double cur_x = x[i] - x[cur];
          double cur_y = y[i] - y[cur];
          // Отсекаем точки назад вдоль оболочки на той же стороне.
          // Можно заменить пометкой в bool in_hull[],
          // которая ставится при добавлении точки в ответ (ans).
          if (side_x*cur_y-side_y*cur_x == 0 && side_x*cur_x+side_y*cur_y < 0) continue;
          double vec = bst_x*cur_y-bst_y*cur_x;
          double dist = cur_x*cur_x+cur_y*cur_y;
          // Берем точку, если она правее текущего кандидата. Или на той же прямой, но ближе.
          if (bsti == -1 || vec < 0 || (vec == 0 && dist < bst_dist)) {
            bsti = i;
            bst_dist = dist;
            bst_x = cur_x;
            bst_y = cur_y;
          } 
        }
        // Сделали полный оборот.
        if (bsti == first) break;
        side_x = bst_x;
        side_y = bst_y;
        and.push_back(bsti);
        cur = bsti;
      }
      return ans;
    }
    Ответ написан
    Комментировать
  • Как заставить нейронку на Python подгонять коэффициенты уравнений?

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

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

    Avg(a1,a2,...an) = (Avg(a2,...an)*(n-1)+a1)/n
    Ответ написан
    Комментировать
  • Какую ошибку допустила в цикле?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Зачем там while True?

    Почему сравнение с 1 в условии? Вроде как результат сравнения будет True или False.

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

    Ну и, последнее. В условии натральные значения x и y, а у вас циклы перебирают и отрицательные значения.
    Ответ написан