Кодируйте каждый элемент набора простым числом.
Пример:
a -> 2
b -> 3
c -> 5
и т. Д.
Теперь вам нужно сохранить еще два списка.
Первый список для простых чисел, второй для их показателей.
Идея такова;когда вы наткнетесь на элемент, запишите его простое число и сколько раз подряд он появится.
Для [a, b, b, c]
вы получите:
[2, 3, 3, 5]
Что можно записать как:
[2, 3^2, 5]
или, точнее:
[2^1, 3^2, 5^1]
, и вы поддерживаете два списка:
[2,3,5] // primes in succession - list [p]
[1,2,1] // exponents - list [e]
Теперь вы перебираете эти два списка от конца до серединыпроверяя, совпадает ли первый элемент [p] ^ [e] с последним элементом;если это так, то второй с последним, последним и т. д. Если все они одинаковы, ваш список можно уменьшить.
В этом примере вы проверяете, если 2^1*5^1 == 3^2*3^2
;и поскольку это не так, его нельзя уменьшить.
Давайте попробуем [a, b, b, a, b, b]
:
Это кодируется как
[2^1, 3^2, 2^1, 3^2]
или
[2, 3, 2, 3] // primes
[1, 2, 1, 2] // exponents
Теперь мы проверяем, если 2^1 * 3^2 == 3^2 * 2^1
(первое простое число, первый показатель степени умножено на последнее простое число, последний показатель степени, а затем сравнивается со вторым числом относительно следующего за последним)
Так как это имеет место, оно сводимо.*
Давайте попробуем [b, b, b, b, b]
:
Это может быть закодировано как
[3^5]
или
[3] // primes
[5] // exponents
Это особый случай: если вы 'у нас есть списки из 1 элемента, тогда ваш исходный список можно привести.
Давайте попробуем [b, b, b, b, a]
:
Это может быть закодировано как
[3^4, 2^1]
или,
[3, 2] // primes
[4, 1] // exponents
Мы проверяем, если 3^4 == 2^1
, а поскольку это не так, ваш список не сводится.
Давайте попробуем [a, b, a, b, a, b]
:
Это может быть закодировано как
[2^1, 3^1, 2^1, 3^1, 2^1, 3^1]
или
[2, 3, 2, 3, 2, 3]
[1, 1, 1, 1, 1, 1]
Попытка описанной выше процедуры работает, потому что 2^1 * 3^1 == 3^1 * 2^1 == 2^1 * 3^1
Итак, алгоритм будет выглядеть примерно так:
Кодировать все числа в простые числа.
ИтерацияПросмотрите список, составьте два списка и заполните их, как описано
Теперь, когда у вас есть два списка, p
и e
, оба из которых имеют длину n
, сделайте следующее:
var start = p[0]^e[0] * p[n-1]^e[n-1]
var reducible = true;
for (int i = 0; i < n/2, ++i) :
if ( (p[i]^e[i] * p[n-i]^e[n-i]) != start ) :
reducible = false;
break;
Примечание. Я не кодировал этот алгоритм и не пробовал его для различных входных данных.Это просто идея.Кроме того, если список можно привести из его длины и длины n
, не должно быть слишком сложно понять, как уменьшить исходный список до его базовой формы.
Второе примечание: если кто-то видитошибка выше, пожалуйста, исправьте меня.Вполне возможно, что ничего из этого не работает, так как уже поздно, и моя концентрация не оптимальна.