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

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

    Можно свести ее к integer linear programming и решать какой-то из множества существующих библиотек/солверов. Если числа маленькие, то можно или полный перебор или какую-то динамику, типа решения задачи о рюкзаке сделать (тут надо будет набранные суммы во всех приборах взять в параметры).

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    У вас переменные correct_Login и correct_Password не инициализируются. Вы их можете затереть в 0, но 1 они никогда не были и не станут.

    Теперь несколько замечаний по коду.

    Не нужно декларировать extern в коде функции для глобальных переменных. Не нужно дописывать '\0' на конце строковых констант, оно там и так будет в конце добавлено автоматически.
    Ответ написан
    1 комментарий
  • Как возвести decimal в степень с плавающей точкой?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Вы что-то напутали.
    1.000001**2**19 тоже возвращает 1.689255227180379. Только что в консоли проверил.

    > costumePow(1.000001, 19)
    1.689255227180379
    > 1.000001**2**19
    1.689255227180379
    Ответ написан
    6 комментариев
  • Где найти неплохое пособие по абсолютно всей математике(если такое есть) и квантовой физике(пособие для новичка, где есть вся база)?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Возьмите центр вписанной (и описанной) окружности. Разделите каждую сторону на 3 равные части. Проведите отрезки из центра во все 5 вершин и 10 точек на сторонах. Вы получите 15 треугольников, с одинаковыми внешними сторонами (1/3 стороны пятиугольника). Еще у всех этих треугольников одинаковые высоты (радиус вписанной окружности). Поэтому они все одинаковой площади. Теперь разбейте их на 3 группы по 5 подряд идущих треугольников - вот и ваши 3 равные по площади куска пятиугольника.

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

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

    Нужно или писать рекурсивную функцию, или итеративно дописывать ко всем элементам массива по одному элементу из сделеющего множества. Просто переведите этот код на с++.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    При копировании назад из временного массива b в массив a у вас индексация с ошибкой. Хоть b индексируется с 0, вы обращаетесь к элементам начиная с s.
    Ответ написан
    1 комментарий
  • Почему в данной ситуации map быстрее unordered_map?

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

    Можно избавиться от таких тривиальных коллизий, если реализовать свою хеш функцию. А там можно хоть (x * 239017l) % (1<<31) возвращать. И то, лучше будет.

    Еще, чтобы избавиться от постоянных рехешированний можно добавить вот это:
    len.reserve(1048576);
    len.max_load_factor(0.25);


    Говорят, что если заранее зарезервировать место и указать load_factor поменьше, то unordered_map будет раз в 10 быстрее.

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Что за A(i, j)?
    Похоже у вас там алгоритм Гаусса, и это должен быть массив.

    Внешний цикл по i нельзя параллелить в Гауссе, а вот вычитание строк можно.
    Допишите перед циклами по j и k это:
    #pragma omp parallel for collapse(2)

    В последних двух циклах тоже нельзя внешний цикл параллелить, ибо результат последующих вычислений зависит от предыдущих итераций. А вот перед внутренним циклом смело втыкайте #pragma omp parallel for.
    Ответ написан
  • Почему вылезает ошибка при компиляции?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Какой-то библиотеки не хватает. Надо ее найти и дописать через -L путь к ней и через -l ее имя.
    Попробуйте дописать:
    -Lc:\Python39\Lib -lpython39
    Ответ написан
  • Зачем нужны нижние подчеркивания перед функциями в C?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    В самом языке это подчеркивание не означает ничего. Это программисты какой-то смысл в эти подчеркивания вкладывают. Может, у авторов кода так принято обозначать "приватные" функции - что-то, что они сами используют, что не положено использовать пользователям библиотеки.
    Ответ написан
    Комментировать
  • Как распараллелить тройной цикл for с помощью OpenMP?

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

    Но, если у вас n меньше количества потоков, то можно использовать диррективу collapse. Подробнее можете почитать в документации (на странице 185).

    Или можете расплющить 3 вложенных цикла в один руками так:
    int n3 = (n-2)*(n-2)*(n-2);
    for (int iteration = 0; iteration < n3; ++iteration) {
      i = iteration / ((n-2)*(n-2)) + 1;
      j = iteration / (n-2) % (n-2) + 1;
      k = iteration % (n-2) + 1;
      // тут идет содержимое трех циклов по i,j,k = 1..n-2
    }

    Это просто перенумерация всех троек значений. Каждую тройку индексов i,j,k можно рассматривать как трехзначное число в (N-2)-ичной системе счисления. Поэтому можно каждое число от 0 до (n-2)^3 разложить в n-2)-ичную систему счисления через / и % и получить три индекса.

    Но collapse и, тем более, ручной вариант будут иметь накладные расходы на вычисление индексов. Поэтому их имеет смысл использовать только если у вас n меньше количества доступных потоков.
    Ответ написан
    Комментировать
  • Почему не происходит перемещение в нужную папку?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Потому что компилятор ищет Python.h во время компиляции. В это время никакой main() не выполняется и chdir ничего не делает. Надо указать компилятору, где искать хедеры.

    Как вы компилируете? Вы под виндовс, видимо, сидите - у вас visual studio или вы gcc используете? Или что-то еще? Используете ли вы cmake или какую-то еще систему сборки? Приведите буквально ту команду/ваши действия, которые приводят к выводу на экран ошибки.

    В итоге все должно вылиться в дописывание флага -I"c:\Python39\include" к команде компиляции. Если какая-то система сборки, то прямо в файле проекта можно как-то указать эту опцию.

    Сам же include нужно делать без всяких путей, просто #include <Python.h>.
    Ответ написан
  • Очень странно работает форматирование массива. В чем ошибка?

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

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

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

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

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

    Так, 323 в десятичной системе, если перевести в 16-ричную будет:
    323 = 16*20+3. Остаток 3, результат 20.
    20 = 16*1+4. Остаток 4, результат 1
    1 = 16*0+1. Остаток 1. результат 0.

    Отсюда получается, что искомое число в 16-ричной системе 143. Проверка 16*16*1+16*4+3 = 256+64+3=323

    Итак, вам надо сделать то же самое, но не в 10-чиной системе, а в k-ичной (ведь переводим не из 10-чной а из k-ичной). Число записано в виде k-ичных цифр в массиве. Это, фактически, длинная арифметика с базой k.

    Для этого надо реализовать деление числа в виде массива цифр на короткое с остатком.
    Это делается со старших разрядов к младшим. Тупо делите каждую цифру с остатком отдельно. Остаток переносите в младший разряд. Последний остаток - это остаток от всего деления. Результаты делений - новые цифры.

    Удобнее хранить цифры от младших к старшим в массиве. Т.е. элемент массива 0 - это единицы. Элемент 1 - это первая степень k. Еще стоит хранить номер последней ненулевой цифры. Смотрите реализацию по ссылке выше.

    Вот пример из условия. Пусть k=666, t=10, число - {2, 179, 113} (в условии цифры от старших к младшим, но мы храним наоборот).

    Делим на 10.

    113/10 = 11 + остаток 3. Переносим 3 в младший разряд (умножив на 666), получаем 3*666+179=2177.
    2177 / 10 = 217 + остаток 7. 7*666+2 = 4664.
    4664 /10 = 466 + остаток 4. Дальше разрядов нет, значит 4 и есть остаток от деления {2, 179, 113} на 10. Результат деления - {466, 217, 11}

    Последний остаток - 4 - это и есть младшая цифра в ответе (он в условии написан - 50241044). Надо продолжать делить результат пока он не окажется 0.

    Повторим для {466, 217, 11}:
    11/10 = 1 + остаток 1. 1*666+217 = 883
    883/10 = 88 + остаток 3. 3*666+446 = 2444
    2444/10 = 244 + остаток 4.
    Опять, последний остаток - это остаток всего деления и следующая цифра в ответе (опять 4).
    Результаты деления - {244, 88, 1}

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

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

    Можно проверить в 2 этапа. Подсчитать A=a*x+b, B=c*x+d. Потом проверить что A*x*x = -B. Но тут нужно заранее отсечь случаи, когда abs(A) > abs(B)/(x*x). Тогда переполнений не будет.

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

    if (d != 0) {
      n = d;
    } else {
      s.push_back(0);
      if (c != 0) {
        n = c;
      } else if (b != 0) {
       n = b;
      } else {
       n = a;
      }
    }
    if (n == 0) {cout << "-1"; return}
    Ответ написан
    2 комментария
  • Как решить задачу с перебором?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Самое простое решение для понимания - полный перебор. Тупо 3 цикла - сколько монет с номиналом 2 взяли, сколько монет с номиналом 3 и сколько монет с номиналом 5. Каждый цикл от 0 до <Сколько осталось набрать> / номинал. Потом проверяем, что сумма сошлась. Более того, можно последний цикл пропустить и просто проверить, что оставшееся можно набрать пятаками.

    bool CanExchange(int n, int have2, int have3, int have5) {
      for(int take2 = 0; take2 <= min(have2, n/2); ++take2) {
        int left2 = n - 2*take2;
        for (int take3 = 0; take3 < min(have3, left2/3); ++take3) {
          int left23 = left2 - take3*3;
          if (left23 % 5 == 0 && left23 / 5 <= have5) {
            return true;
          }
        }
      }
      return false;
    }


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

    Самое быстрое решение - динамическое программирование.

    F(n,k) - можно ли набрать число n первыми k типами монет.

    F(0.0) = 1
    F(*, 0) = 0
    F(n,k) = Sum(i = 0..have[k]) F(n-i*value[k], k-1)

    Фактически, это тот же рекурсивный перебор, только с мемоизацией. Можно переписать это двумя циклами и соптимизировать по памяти до O(n).
    Ответ написан
    Комментировать
  • Почему java выдает ошибку, когда я использую Scanner?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Алексей Мазуркевич, пожалуйста, оформите код в теге code (кнопка "< / >" в редакторе). Сделайте нормально отступы. Иначе почти никто не будет читать ваш код вообще.

    Сообщения об ошибках тоже лучше обернуть в код.
    Ответ написан
    Комментировать
  • Можно ли на ЕГЭ по информатике в задании 6 и 16 просто переписать код в редактор и запустить и сразу получить готовый правильный ответ?

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