Задать вопрос
  • Найти количество чисел, делящихся на одно и тоже число?

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

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

    Быстро получать наибольший общий делитель можно за логарифм с помощью структуры данных дерево отрезков. Общая сложность будет O(n log n).

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

    Общая сложность у этого решения будет O(n sqrt(a)), но его можно ускорить, если предподсчитать для каждого числа от 1 до A один из его простых делителей.
    Ответ написан
    3 комментария
  • Как перемешать массив в псевдослучайной последовательности?

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

    Или можно сортировать хеши, полученные из id тега и id статьи. Например, можно подсчитать tag_id*article_id % n.
    Ответ написан
  • Как вывести полярное уравнение эллипса, гиперболы, параболы?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Берете уравнение вашей функции в виде F(x,y)=0. Подставляете туда x=x0+r*cos(fi), y=y0+r*sin(fi). Выражаете r через fi - вот и уравнение в полярных координатах.

    Тут будет много формул. Во-первых, уравнение F(x,y)=0 надо составить через через эксинцесинтрет и фокальный параметр. Координаты фокуса тоже надо через них выразить. Во-вторых выражение с косинусами и синусами придется хорошенько причесать используя всякие тригонометрические тождества.
    Ответ написан
    Комментировать
  • Почему не работает такое решение?

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

    Чтобы через DFS найти отрицательный цикл - придется перебирать ВСЕ циклы. Для этого надо не помечать вершины как visited. Правда, работать будет очень медленно и почти гарантированно не пройдет по time limit, ибо циклов в гарфе может быть экспоненциально много.

    Edit, вот вам пример. В графе только один отрицательный цикл 1->2->3->1. Но есть еще ребро 1->3. Если вы начнете из 1-ой вершины, потом возьмете ребро 1->3, то дальше вы из вершины 3 никуда не сможете пойти, уберете ее из стека и пометите как visited. Далее вы рассмотрите ребро 1->2 а потом из вершины 2 ребро 2->3 вы пропустите, потому что вершина 3 уже visited.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Очередь с приоритетом реализуется на основе кучи или бинарного дерева поиска (set). В первом случае удаление делается так: Меняете местами первый и последний элемент в куче. Удаляете последний. Потом просеиваете первый элемент вниз, чтобы он встал на свое место. Во втором случае надо просто удалить из сета элемент begin().
    Ответ написан
  • Какую структуру данных надо использовать что бы посчитать уникальные ip в огромном количестве?

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

    Сортировать можно разными способами. Например, читать кусками сколько помещается в память, отсортировать как угодно, записать на диск. Потом получившиеся отсортированные куски можно объединять, как в сортировке слиянием.

    Еще можно использовать radix sort.

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

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Запустите в дебаггере. Он остановится на строке с ошибкой. Проверьте значения всех переменных (zoo - размер вектора? i - чему равно?)
    Ответ написан
    Комментировать
  • Стоит ли смотреть алгоритм архивации, чтобы написать архиватор?

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

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

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

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

    Поскольку n^n делится на a, то n делится на все простые делители a. Поэтому надо разложить a на множители (пусть a= p1^k1*p2^k2 ...)

    Тогда n надо искать в виде k*p1*p2*...

    Это самое k надо перебрать от 1 до максимального ki и проверить, что n^n делится на a. Для этого надо подсчитать, сколько раз k делится на p_i (пусть - это q_i). Тогда надо проверить что, (q_i+1)*n >= k_i для всех простых делителей p_i.
    Ответ написан
  • Как доказать то что множество не является линейно связным?

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

    Вам надо взять f:[0,1] -> R^2, f(0) = (-1,1), f(1) = (1,-1).

    Дальше ввести g(t) = f(t)_y - f(t)_x и там уже применять теорему о промежуточном значении для непрерывных функций.
    Ответ написан
    Комментировать
  • Как найти самую ближайшую точку из массива?

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    my_round(123,-2) = 100.

    Точность говорит, что все цифры после этого индекса должны быть 0. А предыдущая, может увеличится на 1, в зависимости от правил округления.
    Ответ написан
    Комментировать
  • Через сколько клеток проходит отрезок?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что GCD(0,1000) = 1000. А у вас цикл ни разу не выполнится и не найдет ничего.

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

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

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

    Или считайте по формуле ans = from + (to-from+0.0)*time/duration
    Ответ написан
    Комментировать
  • Найдите сумму и количество делителей натурального числа?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    В с++ разве есть оператор and? Попробуйте заменить sqrt на проверку i*i ==n. Видимо, проблемы с точностью. Плюс может быть переполнение. Сумма должна быть long long.
    Ответ написан
    1 комментарий
  • Почему выдает что переменные x,y,z - неинициализированы? Почему выдает что == неуместны и возможно я имел ввиду =?

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

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

    Можно повесить хуку на создание процессов в explorer.exe

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

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

    Проблема в том, что вы, например, пропустите число 2^23, которое входит в первые 10000.

    Вам надо поднимать границы от 22, пока сгенерированная последовательность (первые 10000 чисел) не перестанет менятся. Вы сгенерируете первые 10000 чисел точно, и какие-то дальше в последовательности (возможно с пропусками) - всего будет сильно больше 10000 чисел.

    Но скорее всего, придется поменять алгоритм. Поскольку ограничения маленькие, то тут можно делать что-то типа BFS. Вы вычисляйте числа в последовательности по порядку. И поддерживайте множество возможных следующих чисел. Каждый раз дописывайте минимальное число из кандидатов к последовательности и добавляйте к кандидатам это новое число, умноженное на 2, на 3 или на 5. Это будет квадратичный алгоритм. Можно использовать heap или какой-нибудь set, тогда будет за O(n log n).

    Еще есть линейный алгоритм. Он получается из предыдущего так: все кандидаты разбейте на 3 множества - те, которые получены домножением на 2, на 3 и на 5. Каждое такое множество в итоге будет тупо сама же последовательность, домноженная на 2, 3 или 5. Поэтому единственное, что вам надо знать для полного описания кандидатов - это какое число из последовательности было домножено на 2,3 или 5. Это три индекса.

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

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

    Вам нужно создать прозрачное окно и рисовать в него то, что идет поверх рабочего стола (гуглите "winapi draw in transparent window").

    Чтобы не рисовать поверх каких-то окон - надо в каком-то битмапе нарисовать черным цветом силуэты всех этих окон (надо все окна в системе перебрать - тут вам помогут всякие всякие GetWindowRect, EnumWindows, IsWindowVisible.). И при проприсовке надо этот битмап брать как маску (гуглите "winapi clip region").

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