Геометрическая прогрессия с любым числом строк - PullRequest
4 голосов
/ 29 сентября 2010

У меня может быть любая числовая строка, которая состоит от 2 до 10 чисел. И из этого ряда я должен получить геометрическую прогрессию.

Например: Номер данной строки: 125 5 625 Я должен получить ответ 5. Роу: 128 8 512 Мне нужно получить ответ 4.

Можете ли вы дать мне руку? Я не прошу программу, просто подсказку, я хочу понять ее сам и написать код сам, но, черт возьми, я думал целый день и не мог понять это.

Спасибо.

НЕ ПИШИТЕ ВСЕ ПРОГРАММУ!

Ребята, вы не понимаете, я не могу просто разделить. Я на самом деле должен получить геометрическую прогрессию + показать все числа. В строке 128 8 512 все числа будут: 8 32 128 512

Ответы [ 5 ]

4 голосов
/ 29 сентября 2010

Ответ Сета правильный.Я оставляю здесь этот ответ, чтобы пояснить, почему ответ на 128 8 512 равен 4, потому что у людей, похоже, возникают проблемы с этим.


Элементы геометрической прогрессии можно записать вform c*b^n, где b - это искомое число (b также обязательно больше 1), c - это константа, n - произвольное число.

Лучше всего начинать с наименьшего числа, разложить его на множители и посмотреть на все возможные решения, записав его в форме c*b^n, а затем использовать b на оставшихся числах.Верните самый большой результат, который работает.

Итак, для ваших примеров:

125 5 625

Начните с 5. 5 - простое число, поэтому его можно записать только одним способом: 5 = 1*5^1.Таким образом, ваш b равен 5. Теперь вы можете остановиться, предполагая, что строка на самом деле геометрическая.Если вам необходимо определить, является ли он геометрическим, то проверьте, что b на оставшихся числах.

128 8 512

8 можно записать несколькими способами: 8 = 1*8^1, 8 = 2*2^2, 8 = 2*4^1, 8 = 4*2^1.Таким образом, у вас есть три возможных значения для b, с несколькими различными опциями для c.Попробуйте самое большое сначала.8 не работает.Попробуйте 4.Оно работает!128 = 2*4^3 и 512 = 2*4^4.Так что b - это 4, а c - это 2.

3 15 375

Это немного значит, потому что первое число простое, но не b, это c,Поэтому вам нужно убедиться, что если ваш первый b -кандидат не сработает с оставшимися номерами, вы должны посмотреть на следующее наименьшее число и разложить его.Итак, здесь вы разложите 15: 15 = 15*?^0 (вырожденный регистр), 15 = 3*5^1, 15 = 5*3^1, 15 = 1*15^1.Ответ 5 и 3 = 3*5^0, так что получается.

2 голосов
/ 29 сентября 2010

Редактировать: я думаю, что это должно быть правильно сейчас.

Этот алгоритм не полагается на факторинг, только на Евклидов алгоритм иего близкий вариант.Это делает его немного более математически сложным, чем решение, использующее факторинг, но оно будет НАМНОГО быстрее.Если вы понимаете Евклидов алгоритм и логарифмы, математика не должна быть проблемой.

(1) Сортировать набор чисел.У вас есть числа вида ab^{n1} < .. < ab^{nk}.

Пример: (3 * 2, 3*2^5, 3*2^7, 3*2^13)

(2) Сформировать новый список, чей n-й элемент (n + 1) -ого элемента отсортированного спискаделится на (п) й.Теперь у вас есть b^{n2 - n1}, b^{n3 - n2}, ..., b^{nk - n(k-1)}.

(продолжение) Пример: (2^4, 2^2, 2^6)

Определить d_i = n_(i+1) - n_i (не программируйте это - вы не могли этого сделать, даже если хотели, так как n_i неизвестны -это просто для того, чтобы объяснить, как работает программа.

(продолжение) Пример: d_1 = 4, d_2 = 2, d_3 = 6

Обратите внимание, что в нашем примере задачи мы можем взять либо (a = 3, b = 2), либо (a = 3/2, b = 4).Суть в том, что любая степень «реального» * ​​1032 *, которая делит все записи в списке с шага (2), является правильным ответом.Отсюда следует, что мы можем повысить b до любой степени, которая делит все d_i (в данном случае любую степень, которая делит 4, 2 и 6).Проблема в том, что мы не знаем ни b, ни d_i.Но если мы допустим m = gcd(d_1, ... d_(k-1)), то мы МОЖЕМ найти b^m, что достаточно.

ПРИМЕЧАНИЕ: Учитывая b^i и b^j, мы можем найти b^gcd(i, j), используя:

log(b^i) / log(b^j) = (i log b) / (j log b) = i/j

Это позволяет нам использовать модифицированную версию евклидова алгоритма для поиска b^gcd(i, j).«Действие» - все в показателях степени: сложение было заменено умножением, умножением с возведением в степень и (следовательно) частными с логарифмами:

import math
def power_remainder(a, b):
    q = int(math.log(a) / math.log(b))
    return a / (b ** q)        

def power_gcd(a, b):
    while b != 1:
    a, b = b, power_remainder(a, b)
    return a

(3) Поскольку все элементы исходного набора отличаютсяпо степеням r = b^gcd(d_1, ..., d_(k-1)) все они имеют форму cr^n, по желанию.Однако c не может быть целым числом.Дайте мне знать, если это проблема.

0 голосов
/ 30 сентября 2010

Сет Ответ неверен, при условии, что решение не решает 128 8 2048 строку, например (2 * 4 ^ x), вы получите: 8 128 2048 => 16 16 => GCD = 16

Это правда, что решение является фактором этого результата, но вам нужно будет учесть его и проверить один за другим, какой правильный ответ, в этом случае вам нужно будет проверить факторы решения в обратном порядке 16, 8, 4, 2 пока вы не увидите 4 соответствует всем условиям.

0 голосов
/ 29 сентября 2010

То, что вы хотите, это знать Величайший Общий делитель всех чисел подряд.

Один из способов - проверить, можно ли разделить их все на меньшее число в строке.

Если нет, попробуйте половину меньшего числа в строке.

Затем продолжайте идти вниз, пока не найдете число, которое делит их все или ваш делитель будет равен 1.

0 голосов
/ 29 сентября 2010

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

...