Die Herausforderung
Es gibt N Städte, die in einer geraden Linie ausgerichtet sind. Die i-te Stadt liegt A[i]
Kilometer rechts vom Ursprung. Keine zwei Städte werden am selben Ort sein.
Sie werden mit einigen Kraftwerken ein Stromnetz bauen. Kraftwerke müssen in einer Stadt gebaut werden. Sie dürfen jedoch nur K
(<N) Kraftwerke bauen, daher gibt es einige Städte ohne Kraftwerke. Für jede Stadt ohne Kraftwerke müssen Sie ein Kabel zwischen ihr und der nächstgelegenen Stadt mit einem Kraftwerk bauen .
Wenn sich beispielsweise drei Städte in befinden 0, 1, 2
und nur die Stadt in 0
ein Kraftwerk hat, müssen Sie zwei Kabel bauen, eines von 2
bis 0
(2 km) und das andere von 1
bis0
Gesamtlänge von 3 (1 km) bauen .
Gegeben K
und Positionen der Städte (A
) sollten Sie die minimalen Kabelkilometer berechnen, die Sie zum Aufbau des Netzes benötigen.
Beispiel Testfälle
K = 1, A = [0, 2, 4, 6, 8] : 12
# build power plant in the city at position 4, total length = 4 + 2 + 0 + 2 + 4 = 12
K = 3, A = [0, 1, 10, 11, 20, 21, 22, 30, 32] : 23
# build power plants in cities at positions 0, 10 and 22
K = 5, A = [0, 1, 3, 6, 8, 11, 14] : 3
# build power plants in all cities except those at positions 0, 3
K = 6, A = [0, 1, 3, 6, 8, 14, 15, 18, 29, 30, 38, 41, 45, 46, 49, 58, 66, 72, 83, 84] : 49
Spezifikationen
Sie sollten eine Funktion oder ein Programm implementieren, das eine positive Ganzzahl
K
und eine Liste von GanzzahlenA
in beliebiger Form akzeptiert und eine Ganzzahl ausgibt / zurückgibt, die die Antwort darstellt.A
wird in aufsteigender Reihenfolge sortiert, und alle Elemente sind nicht negative ganze Zahlen.A[0] = 0
undA[N-1]
wird nicht mehr als 1000N sein.Beachten Sie, dass die Ausgabe eine Größe von 1000 N 2 hat. In größeren Fällen benötigen Sie in einigen Sprachen möglicherweise 64-Bit-Ganzzahlen.
Multithreading ist nicht zulässig (ich werde die Affinität Ihres Programms bei der Beurteilung auf nur 1 Kern setzen). Compiler-Optimierungen (wie
-O2
in C) sind zulässig.
Wertung
Ich werde Ihren Code auf meinem Computer (Ubuntu 16.04 mit Intel i7-3770S Prozessor) mit unterschiedlicher Größe von Testfällen zeitlich festlegen. Insbesondere werde ich einige Testfälle mit N = floor (2 x / 5 ) generieren, wobei x eine positive ganze Zahl ist.
Ihre Punktzahl ist der x-Wert des kleinsten Testfalls, für den Ihr Programm mehr als 10 Sekunden oder 1 GB Speicher benötigt, oder Sie geben keine korrekte Antwort.- Die Antwort mit der höchsten Punktzahl gewinnt. Wenn zwei Antworten die gleiche Punktzahl erhalten, gewinnt die frühere Antwort.
Alle Programme werden nach denselben Testfällen beurteilt.
Fühlen Sie sich frei, Ihre eigenen Scorings zu posten. Erklärungen Ihres Algorithmus werden angeregt.
Bonus
Dies ist mein C ++ - Programm, es erhält 108 Punkte . Sie können den SHA-256-Digest überprüfen9a87fa183bad1e3a83d2df326682598796a216b3a4262c32f71dfb06df12935d
anhand des gesamten Codesegments (ohne Fußzeile) im Link .
Der Algorithmus kombiniert die binäre Suche und die Knuth-Optimierung, um die richtige Strafe für jede Pflanze zu finden und die gewünschte Zahl zu erhalten. Die Komplexität ist O (N log N log A [N-1]). Ich war überrascht, dass das Programm eine höhere Punktzahl als die Lösung O (N log A [N − 1]) von Anders Kaseorg erhielt . Dies liegt wahrscheinlich daran, dass der Log-Fall in Knuths Optimierung normalerweise nicht auftritt.
Beachten Sie, dass diese Herausforderung mit IOI 2000 Post Office identisch ist . Die ursprünglichen Bedingungen sind jedoch N <= 300 und K <= 30.
quelle
2^^(x/5)
: was ist die Bedeutung ? Können Sie nur eine Obergrenze für N angeben?N=21( = floor(2^(22/5)) )
in 10 Sekunden fertig ist , aber nicht fertig istN=24( = floor(2^(23/5)) )
, ist 23 die Punktzahl. Ich habe keine Obergrenze verwendet, da die Unterschiede zwischen den verschiedenen Algorithmen zu groß sind. Wenn ich N Zum Beispiel setzen <= 40, wird es kaum einen Unterschied zwischenO(KN^2)
undO(KN^3)
, aberO(2^N)
nicht einmal in vernünftiger Zeit zu beenden.Antworten:
Rost , Score = 104
Dies ist eine Implementierung des von Grønlund et al. (2017) am Ende von §3.3.1, obwohl ich einer langen Zitierkette folgen und einige fehlende Details eintragen musste. Es läuft in O ( N log A [ N - 1]).
Kompilieren mit
rustc -O
. Das Eingabeformat befindet sichK
in der ersten Zeile, gefolgt von den Einträgen vonA
einem Eintrag pro Zeile, alle auf stdin.(Hinweis: Ich übermittle dies eine Stunde nach Ablauf der Prämienfrist, erwarte jedoch, dass die letzte Version, die ich vor Ablauf der Prämienfrist eingereicht habe und die in O ( N log N log A [ N - 1]) abgelaufen ist, etwa 94 Punkte erzielt .)
Probieren Sie es online!
Rost , Pretest Score = 73
Kompilieren mit
rustc -O
. Das Eingabeformat befindet sichK
in der ersten Zeile, gefolgt von den Einträgen vonA
einem Eintrag pro Zeile, alle auf stdin.Probieren Sie es online!
quelle
61
, aber das liegt am Überlauf vonu32
. Vielleicht können Sie auf 64-Bit-Integer-Typ ändern?type Cost = u32
zutype Cost = u64
?73
.C, Score = 56
Inhalt von
a.c
:Shell-Skript zum Kompilieren und Testen des oben genannten:
n = 776 dauert 6,2 s, n = 891 dauert 12 sn = 1176 dauert 5,9 s, n = 1351 dauert etwas mehr als 10 sn = 1351 dauert 8,7 s, n = 1552 dauert mehr als 10 s (mit k = 2 * n / 3) auf meiner
Intel(R) Core(TM) i3-2375M CPU @ 1.50GHz
quelle
syntax/c.vim
.C ++, Score = 53
Die Lösung hatte ich im Kommentar gesagt.
O(n²×k)
. (jetzt habe ich es gelöscht weil es nicht mehr nötig ist) Kann wohl auf reduziert werdenO(n×k)
.Die Eingabe ist ziemlich flexibel. In der ersten Zeile ist die erste Zahl
k
, die anderen Zahlen sind Elemente des Arraysa
. Wenn sie jedoch in engen Klammern stehen, werden die Eingaben nicht mehr gelesen. Eingaben wie werdenK = 1, A = [0, 2, 4, 6, 8] : 12
also akzeptiert.Probieren Sie es online!
Generieren Sie zufällige Testfälle. (Eingabe
N
und optional Stadtbereich,1000×N
standardmäßig)quelle
int
s inint64_t
s.C #, Score = 23
Ich bin mir sicher, dass dies diese Herausforderung nicht gewinnen wird. Ich wollte lediglich eine erste (und sehr einfache) Antwort veröffentlichen, um andere zu ermutigen, ihre Algorithmen zu veröffentlichen und meine zu verbessern. Dieser Code muss als Konsolenprojekt kompiliert werden, das das Combinatorics-Paket von NuGet verwendet. Die Hauptmethode enthält einige Aufrufe der
Build
Methode zum Testen der vorgeschlagenen Fälle.Wirklich einfache Erklärung: Berechnen Sie für jede Kombination
c
vonk
Elementen ausa
die Summe der Abstände von jedem Elementa
zum nächsten Element inc
und geben Sie die Kombination mit dem geringsten Gesamtabstand zurück.Einzeilige Version der
Build
Methode (wahrscheinlich langsamer als die ursprüngliche, erweiterte Version; dazu muss ein Verweis hinzugefügt werdenSystem.Linq
):quelle
C ++, Score = 48
Gebrauchseingabe: NKA [1] A [2] ... A [N]
quelle
step
auf 70 erhöhen, beträgt Ihr Pretest-Score 60.Ruby , Score = 23
Probieren Sie es online!
Ich glaube nicht, dass es gewinnen wird, aber ich wollte es versuchen.
quelle
JavaScript (ES6) (Node.js) , Score = 10
Neuer Algorithmus, wird erklären, ob er diesmal tatsächlich funktioniert.
Probieren Sie es online!
Führe den gleichen Weg wie den anderen.
JavaScript (ES6) (Node.js) , Pretest-Score = 12
Umriss des Algorithmus:
Das Programm ordnet die Daten zuerst der Stadtklasse zu, die einige Datenpunkte ordnet:
Das Array wird dann in die Group-Klasse geworfen, die Folgendes enthält:
Nun teilt der Algorithmus die Gruppen so lange auf, wie zwei oder mehr Kraftwerke zu platzieren sind.
Schließlich ordnet es die Gruppen den Zentren zu und fasst sie alle zusammen.
Wie läuft man:
Mit Node.js ausführen (v9.2.0 wurde für die Erstellung verwendet)
Ausführen des Programms mit generierten Testfällen für Punktzahl 70:
Ausführen des Programms mit 1 Kraftwerk und Städten [0,3,5]:
Code:
Probieren Sie es online!
Ich werde den auskommentierten Code in den nächsten Tagen bereinigen, da ich immer noch daran arbeite. Ich wollte nur sehen, ob dies mehr als nur die kleinen Fälle passiert.
quelle
K = 2, A = [0, 21, 31, 45, 49, 54]
. Die richtige Antwort ist 40, aber Ihr Programm gibt 51 aus.K = 2, A = [0, 4, 7, 9, 10]
. Richtig: 7, Ihre Antwort: 8.K = 2, A = [0, 1, 3, 4, 9]
. Richtig: 6, Ihre Antwort: 7.C (nicht konkurrierend, Pretest Score = 76)
Dies ist ein Versuch, @ AndersKaseorgs zweite Rust-Lösung in C zu übersetzen.
Kompilieren mit:
quelle
Sauber , Score = 65
Kompilieren mit:
clm -h 1024M -gci 32M -gcf 32 -s 32M -t -nci -ou -fusion -dynamics -IL Platform main
Nimmt
K
und dann jedes Element vonA
als Befehlszeilenargumente.quelle