Ответы пользователя по тегу Математика
  • Какой алгоритм использовать для нахождение уравнения поверхности по 3 точками?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Пусть точка p=(x,y,z) принадлежит плоскости. Пусть 3 точки - p1, p2, p3.

    Тогда вектор (p-p1) должен раскладываться на вектора p2-p1 и p3-p1.

    Т.е. определитель матрицы 3x3 из этих трех векторов должен быть нулевым.

    det {{x-p1x, p2x-p1x, p3x-p1x},
     {y-p1y, p2y-p1y, p3y-p1y},
     {z-p1z, p2z-p1z, p3z-p1z}} = 0


    Раскрываете определитель по первому столбцу и получаете
    A = det({{p2y-p1y, p3y-p1y}, {p2z-p1z, p3z-p1z}})
    И т.д.
    D = -p1x*A-p1y*B-p1z*C
    Ответ написан
  • Что думаете об этом решении задачи?

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

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

    Что касается кода: ваш разбор случаев, что там больше - весьма странен. Код тяжело читать и он в несколько раз медленее, чем мог бы быть из-за постоянных вызовов максимума и минимума. Может даже медленнее простого вычисления чисел фиббоначи без пропусков нечетных.

    Заведите вы третью временную переменную и считайте через нее, чтобы в цикле всегда n было большим числом (m = 4*n+b; b=n; n=m). Или вообще воспользуйтесь фишками питона и делайте множественное присвоение:
    b, n = n, 4*n+b;
    Ответ написан
    8 комментариев
  • Как практически использовать теорему Колмогорова-Арнольда?

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

    Например, x*y*z вы в сумму никогда не разложите. Зато, если взять f(a,b) = a*b, то можно сделать f(x,f(y,z)).

    Это хорошо для оптимизации

    Эта суперпозиция не будет лучше для оптимизации ни с какой точки зрения.

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

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

    Далее, фигура повторяется блоками 2x2, т.е. вам не важны сами координаты, а только их положение в блоке.

    Для высчитывания координаты в блоке можно или вычитать 2, пока координата больше 2, или вычесть из x (floor(x) - floor(x)%2). floor(x) даст целые числа. Потом надо это число сделать четным, возможно вычесть 1. floor(x)%2 - как раз и даст нам, что надо вычесть.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Разбейте область на простые фигуры (квадраты, окружности, полуплоскости) и опишите логически. Вроде точка в области, если она в фигуре А, но не фигуре Б; или в фигурах В и Г, или в фигурах Д и Е.

    Далее перевести это в код - это один if с кучей условий объедененных логическими или (||) или логическими И (&&).
    Ответ написан
    Комментировать
  • Как разбить числа по группам так, чтобы в группах находились близкие по значению числа?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Надо ввести какую-то метрику - какая-то числовая оценка, которая говорила бы вам, почему [[1,2],[3,4],[5,6]] лучше чем [[1,2,3,4],[5],[6]]. Например, можно взять максимальную разность двух чисел в любой группе. Или сумму квадратов расстояний от всех чисел до среднего в их группе. Или минимальное расстояние между числами в разных группах (это надо максимизировать).

    Потом можно применять какой-то из известных методов кластеризации, в зависимости от выбранной метрики. В случае одного измерения, как у вас (просто числа) можно еще применить и динамическое программирование. Этот метод работает для практически любой вменяемой метрики. Считайте функцию F(n,k) - лучшая возможная метрика если первые n чисел разбить на k групп. Для пересчета надо перебрать, сколько чисел идет в последнюю группу (i), и пересчитать метрику на основе F(n-i, k-1). из всех вариантов выбрать лучший.
    Ответ написан
    Комментировать
  • Что есть максимальная сумма делителей?

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

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

    Далее, используя эти данные, можно подсчитать сумму всех простых делителей используя формулу S=(p1^(k1+1)-1)/(1-p1)*...*(pm^(km+1)-1)/(1-pm) (тут p1^k1...pm^km - разложение числа на простые множители).

    Надо считать эту сумму делителей от меньших чисел к большим (обозначим ее S(n)). Тогда S(n) = S(n/p^k)*(p^k*p-1)/(p-1).

    Но это так, для любопытных. Я думаю в вашей задаче достаточно для кадого числа проверять все делители до корня (а оставшиеся делители получаются как n/i, если i - делитель до корня). Надо только аккуратно разобрать случай, когда i = sqrt(n) - тогда второй делитель не надо рассматривать, ибо это вторая копия того же самого.
    Ответ написан
    3 комментария
  • Как повернуть прямую на систему координат?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Вам надо арктангенс брать от отношения, а не тангенс (y2-y1) / (x2-x1).
    Ответ написан
  • Как вычислить ценовой рейтинг товара?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Это называется интерполяция. Вы знаете, что f(a) = 10, f(b)=5. Вам надо найти f(c), при чем f должна попадать под здравый смысл (монтонная, непрерывная функция).

    например, можно взять линейную инерполяцию, тогда f(x) = 10-(x-a)/(b-a)*5.
    Ответ написан
    1 комментарий
  • Правильная реализация уровней?

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

    Могу предположить, что в описанном вами случае надо 2^level * 10 опыта до следующего уровня.
    Ответ написан
    1 комментарий
  • Итерационное вычисление больших степеней числа по цифрам?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Есть неалгоритмический способ ускорить ваше решение - храните в каждой ячейке массива не одну цифру - а несколько. Фактически, проводите вычисления в системе счисления 10000, вместо 10. Или даже 1000000000 - но тогда надо временные вычисления (умножение) делать в int64_t, чтобы переполнения не было.

    Еше, при выводе такого числа надо выводить ведущие нули для всех ячеек, кроме самой старшей.

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

    Но в таком виде алгоритм будет даже медленнее на больших числах. Ему потребуется O(log K) умножений большого на большое (которое делается за O(L^2), где L - длина числа, которая будет O(K)). Итоговая сложность этого алгорима будет O(K^2 log K).

    Когда как ваше текущее решение делает K коротких умножений (Каждое - O(K)) - всего O(k^2) операций. Но если применять быстрое умножение длинных чисел через быстрое преобразование Фурье то итоговая сложность будет O(K log^2 K log log K). Для power=100 особо вы разницы не почуствуете, даже медленнее будет, но вот при каких-нибудь 10000 уже будет заметно быстрее.

    Советую попробовать обычные оптимизации, прежде чем браться за преобразование фурье.

    Еще, вместо хранения конца числа в виде особого значения 10 - вам стоит отдельно хранить длину числа в какой-то переменной с говорящим названием (хотя бы len). Тогда код будет сильно читабельнее.
    Ответ написан
    2 комментария
  • Геометрическая прогрессия и сложный процент это одно и то же?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Нет. Распишите формулы, они будут разные. В прогрессии каждый раз добавляется степень коэффициента q. В проценте происходит домножение на (1+q):
    A+Aq+Aq^2+Aq^3+...
    A+Aq+(Aq+Aq^2)+(Aq+2*Aq^2+Aq^3)+...
    Ответ написан
    Комментировать
  • Как решить задачу, используя одну формулу и не успользуя if, else, elif?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Бинарный поиск.
    Можно реализовать без if-ов вообще.
    Суть в том, что у вас есть текущий отрезок. Находите середину, спрашиваете про нее. Получаете ответ R = 0 или 1. Потом прибавляете половину отрезка к левой границе, умноженную на R и вычитаете ее из правой границы, умноженную на 1-R. Таким образом сдвинется только одна граница. Остается вопрос, что делать с выходом из цикла. Там же внутри if запрятан.

    Можно или скопировать код 7 раз (2^7 > 100), или иметь бесконечный цикл, который будет сравнивать границы и вызвать одну из двух функций в массиве на 2 элемента. Одна из функций выведет ответ и завершит работу программы через exit. Вторая - не будет делать ничего.
    Ответ написан
    Комментировать
  • Сортировка точек против часовой стрелки?

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

    Вот только угол идет от -pi до pi, а не от 0 до 2pi. Если вы хотите, чтобы первая точка была {1, 0}, то надо к отрицательным углам прибавлять 2pi перед сравнением.

    Это будет работать, но не очень оптимально. Atan - медленная штука. Можно сравнивать знаки координат сначала.

    Если одна точка с положительным y, а другая с отрицательным - положительная идет раньше. Если одна из точек имеет y=0 или знаки одинаковые - сравнивайте знаки по x. Выше и ниже оси OX - сравнения должны давать разные выводы (выше оси OX, положительные x идут раньше отрицательных, ниже оси OX - наоборот).

    Или для каждой точки в зависимости от двух знаков координат надо назначить квадрант от 1 до 4. И сначала сортировать по ним.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Координаты центра ромба {x,y} - {130/2*(x-y), 84/2*(x+y)}

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

    Далее надо найти координаты нескольких прямых и можно вывести формулу.

    Второй вариант - через геометрию векторов (это линейная алгебра, или еще нет - как это в школе-то называется вообще?). Нарисуйте вектор из ромба {0,0} в ромбы {1,0} и {0,1}. Ясно, что ромб с координатами {x,y} можно получить сложив x раз первый вектор и y раз второй. Подставляя координаты получите ту же формулу.
    Ответ написан
    Комментировать
  • Как вывести формулу?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Сначала заменой x=x'+x0, y=y'+y0 можно убрать коэффициенты D и E и считать, что центр лежит в точке {0, 0}.

    Дальше надо подобрать такой угол поворота, что коэффициент при xy станет нулем. Тогда останется что-то вроде A'x^2+C'y^2 + F' = 0 - а значит эллипс выравнен вдоль осей и это был искомый угол.

    Подставляя формулы поворота системы координат x=x' cosa-y' sina и y=x' sina + y' cosa и приводя слагаемые можно составить уравнение на этот самый коэффициент перед xy. Он будет озависить только от A,B,C и sina, cosa. Далее это тригонометрическое уравнение надо причесать и решить. Вам придется воспользоваться вот этой формулой для котангенса двойного угла: maxresdefault.jpg.

    У вас будет уравнение с косинусами, синусами. Его можно элементарно привести к тангенсу. Далее применяете эту формулу и получаете ответ.
    Ответ написан
    Комментировать
  • Что не так с синусом?

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

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

    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 Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    my_round(123,-2) = 100.

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

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Используйте функцию max.

    Значение в каждой ячейке будет
    max(0, (тукущее значение) - max(0, (платеж) - (сумма всех следующих ячеек)))


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