Die Folge von Dreiecken wird durch die Summe der natürlichen Zahlen dargestellt, das siebte Dreieck ist 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. Die ersten 10 Terme des Dreiecks sind:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... Wird sein.
Das Folgende ist eine Liste der Kürzungen für die ersten sieben Begriffe.
1: 1 3: 1,3 6: 1,2,3,6 10: 1,2,5,10 15: 1,3,5,15 21: 1,3,7,21 28: 1,2,4,7,14,28
Daraus ist ersichtlich, dass das siebte Dreieck 28 das erste Dreieck mit mehr als fünf Verkleinerungen ist.
Also, was sind die ersten Dreiecke mit mehr als 500 Reduzierungen? http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2012
Es ist schwierig, eine Dreieckszahl zu sagen, aber der Punkt ist, dass eine Dreieckszahl eine Zahl ist, die durch die Summe der natürlichen Zahlen von 1 bis n dargestellt wird. Die Summe der natürlichen Zahlen von 1 bis n wird durch die folgende Formel ausgedrückt.
n * (n+1) /2
Und da n und (n + 1) zueinander Primzahlen sind (keinen gemeinsamen Primfaktor haben), sind n / 2 und n + 1 oder n und (n + 1) / 2 auch Primzahlen zueinander. Ob es n / 2 und n + 1 oder n und (n + 1) / 2 sein soll, hängt davon ab, welches gerade ist. Die Anzahl der Fraktionen, die durch Multiplizieren der natürlichen Zahlen n1 und n2 erhalten werden, die sich gegenseitig primieren, ist gleich der Anzahl, die durch Multiplizieren der Anzahl der Fraktionen von n1 und der Anzahl der Fraktionen von n2 erhalten wird.
Basierend auf den obigen mathematischen Überlegungen werden wir diese Frage mit dem folgenden Algorithmus beantworten.
import mymath
def cof():
pri = mymath.get_primes(10**4)
n = 1
num_fac = 1
lim = 500
n1_fac = mymath.get_number_of_factor(n,pri)
while num_fac < lim:
n += 1
if (n+1)%2:
n2_fac = mymath.get_number_of_factor(n+1,pri)
else:
n2_fac = mymath.get_number_of_factor((n+1)/2,pri)
num_fac = n1_fac * n2_fac
n1_fac = n2_fac
print n * (n+1) / 2
Als ich versuchte, es auszuführen, waren es 1,62 Sekunden pro Ausführung, was auf der Poop-Ebene langsam ist. Als ich mich fragte, ob ich es irgendwie beschleunigen könnte, wurde mir klar, dass die Faktorisierung in erster Linie die Ursache für die Langsamkeit war. Mir ist aufgefallen, dass dieselbe Methode wie Eratostenes verwendet werden kann, um den Bruchteil jeder Zahl ohne Division zu erhalten.
Für mehr Details,
Die folgenden Funktionen wurden zu mymath hinzugefügt.
def factor_seq(max):
ret = [[0]]
for i in range(max):
ret += [[1]]
seq = range(max+1)
for i in seq[2:max//2+1]:
for j in seq[i*2::i]:
ret[j] += [i]
return ret
Codiert mit den oben genannten
def cof2():
fq = mymath2.factor_seq(10**5)
n = 1
num_fac = 1
lim = 500
n1_fac = len(fq[n])
while num_fac < lim:
n += 1
if (n+1)%2:
n2_fac = len(fq[n+1])
else:
n2_fac = len(fq[(n+1)/2])
num_fac = n1_fac * n2_fac
n1_fac = n2_fac
print n * (n+1) / 2
Infolgedessen waren es 640 ms, ein Level, das ich ertragen konnte. Wenn Sie in factor_seq "ret [j] + = [i]" in "ret [j] + = 1" ändern, erhalten Sie möglicherweise eine Bruchzahl. Ich denke, es wird schneller, wenn Sie diese verwenden.
Recommended Posts