すべてのセット要素を素数でエンコードします。
元:
a -> 2
b -> 3
c -> 5
等
ここで、維持するためにさらに 2 つのリストが必要です。
最初のリストは素数用で、2 番目はその指数用です。
アイデアは次のとおりです。要素に出くわしたら、それが素数であり、連続して何回出現するかを記録します。
の場合[a, b, b, c]、次のようになります。
[2, 3, 3, 5]
次のように記録できます。
[2, 3^2, 5]
または、より正確には:
[2^1, 3^2, 5^1]
2 つのリストを維持します。
[2,3,5] // primes in succession - list [p]
[1,2,1] // exponents - list [e]
ここで、最初の要素 [p]^[e] が最後の要素と同じかどうかをチェックして、これら 2 つのリストを端から端まで反復します。そうである場合は、最後から次の 2 番目など... それらがすべて同じである場合は、リストを減らすことができます。
この例では、次のことを確認します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(最初の素数、最初の指数に最後の素数を掛けたもの、最後の指数、そして 2 番目と最後から 2 番目のものを比較するかどうか) をチェックします。
これが成り立つので、還元可能です。
試してみましょう[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
したがって、アルゴリズムは次のようになります。
すべての数値を素数にエンコードします。
リストを反復処理し、2 つのリストを作成して、説明どおりに入力します
2 つのリスト と ができ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、元のリストを基本的な形に縮約する方法を理解するのはそれほど難しくありません。
2 番目の注意: 誰かが上記の間違いを見つけた場合は、訂正してください。遅くて私の集中力が最適ではないため、これが実際に機能しない可能性があります.