Задать вопрос
  • Как определить длину кратчайшего цикла в неориентированном графе?

    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, а у вас циклы перебирают и отрицательные значения.
    Ответ написан
  • C++ WinForm Как правильно вывести массив структур переданный через указатель?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    auto ch_kol() {
        baseProgr base[max];
        return &base;


    Вы тут возвращаете адрес локальной переменной. Так делать нельзя. При выходе из функции локальная переменная перестает существовать и у вас указатель на фигню остается.

    Переменная должна быть глобальная, частью класса или выделятся через new.
    Ответ написан
    Комментировать
  • Что требуется в задаче Python?

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

    В первой задаче надо выбрать какие-то числа, в числах выбрать какие-то цифры (всего не более k цифр) и заменить их другими цифрами так, чтобы сумма увеличилась как можно больше. Очевидно, что заменять надо старшие цифры и всегда на 9. Поэтому можно сразу сказать, что если мы в числе 128694 заменяем 3 цифры - то это "128" и получится 999694.

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

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

    Можно еще немного порисовать тесты на бумажке и понять, что каждое число можно рассматривать как набор цифр. Каждая цифра отдельна. Ибо замена одной цифры увеличит сумму на (9-цифра)*10^(разряд цифры) независимо от остальных цифр. Т.е. задача еще преобразуется - есть куча цифр каждая с известным профитом, если ее заменить. Надо не более k из них взять, так что бы сумма изменения была максимальна.

    Теперь понятно, что задача решается сортировкой. Считатете для каждой цифры сумму профита, все это складываете в массив (длины максимум 10*n). Сортируете по убыванию и берете сумму первых k значений.

    Вотрая задача - опять же медленно читайте. Я не могу за вас понять. Объяснить как-то проще условие тоже не могу. Попробуйте порисовать тесты в виде пронумерованных точек, от которых стрелочки идут к значению a[i] - кому они дают подарки. Вам надо ровно одну стрелочку переместить так, что бы все стрелочки замкнулись в один круг.

    Для решения надо понять, а что будет, если не менять ни одно число? Путь из точки 1 будет или циклом или чем-то вроде цифры "6". Сначала какой-то хвост, который зацикливается где-то на середине.

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

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

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

    В питоне нет фигурных скобок, как в си, или begin/end, как в паскале. Содержимое блока (if/for) выделяется отступом.
    Ответ написан
    Комментировать
  • Как правильно оформить шаблон функции в классе с++?

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

    Посмотрите примеры.
    Ответ написан
    Комментировать
  • Запуск приложения на стороне клиента из php на web- странице?

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

    Сделать это незаметно для пользовател в браузере невозможно из-за соображений безопасности.
    Ответ написан
    2 комментария
  • Как написать функцию добавления/удаления элемента в массив?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    На Си будет практически то же самое. Только вместо new надо делать malloc, а вместо delete - free.
    Ответ написан
    4 комментария
  • Как работает эта часть кода?

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

    Вот так этот цикл и пробегается по всем цифрам числа a.
    Ответ написан
    Комментировать
  • Ошибка в игре на Qt (C++) Аварийное завершение, как решить?

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

    Дебаггер покажет конкретную позицию, где произошла ошибка. Там уже, видя, какая переменная некоректна надо смотреть логику вокруг нее.
    Ответ написан
    4 комментария
  • Почему не работает dynamic_cast?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Определение функции шаблона должно быть inline в .h файле (вставьте код из code.cpp в code.h).

    Ну, или в code.cpp файле добавьте куда-то строку
    findViewById<WEngine::TextView*>;

    Это все потому, что в C++ архаичная система хедеров. Когда компилится main.cpp, он не видит определения метода, только декларацию из code.h. Когда компилится code.cpp, он не знает, что main понадобится инстанциирование шаблона с каким-то типом. Поэтому не создает его. А потом линкер уже ругается, что не может найти функцию.
    Ответ написан
    Комментировать