Bestimmen Sie bei zwei zusammenhängenden Formen desselben Bereichs den optimalen Weg, um die erste Form in eine minimale Anzahl zusammenhängender Segmente zu unterteilen, sodass sie neu angeordnet werden können, um die zweite Form zu bilden. Mit anderen Worten, ermitteln Sie die Mindestanzahl der erforderlichen Segmente, die beide Formen bilden können.
"Zusammenhängend" bedeutet, dass jedes Quadrat in der Form von jedem anderen Quadrat aus erreicht werden kann, indem man über Kanten geht. Formen und Segmente dürfen Löcher haben.
"Neu anordnen" bedeutet, dass Sie die Segmente verschieben. Sie können sie übersetzen, drehen und reflektieren.
Die Formen sind in einem Raster enthalten. Mit anderen Worten, jede Form besteht aus einer Sammlung von Einheitsquadraten, die durch ihre Ecken / Kanten verbunden sind.
Eingabespezifikationen
Die Eingabe wird in einem angemessenen Format bereitgestellt - Liste der Punkte, Array von Zeichenfolgen, die jedes Raster darstellen usw. Auf Anfrage können Sie auch die Größe des Rasters übernehmen. Die Gitter haben die gleichen Abmessungen und die beiden Formen haben garantiert die gleiche Fläche, und die Fläche ist positiv.
Ausgabespezifikationen
Die Ausgabe sollte nur eine einzelne positive Ganzzahl sein. Beachten Sie, dass es immer eine positive Antwort gibt, da Sie im schlimmsten Fall die Formen einfach in N
Einheitsquadrate unterteilen.
Beispiele
Die Beispiele werden als Raster .
dargestellt, wobei ein Leerzeichen und ein #
Teil der Form dargestellt werden.
Fall 1
Eingang
.....
.###.
.#.#.
.###.
.....
###..
..#..
..#..
..###
.....
Ausgabe
2
Erläuterung
Sie können es in zwei L-förmige 4er-Blöcke unterteilen:
#
###
Fall 2
Eingang
#...
##..
.#..
.##.
.##.
####
....
....
Ausgabe
2
Erläuterung
Sie können die Formen folgendermaßen aufteilen:
A...
AA..
.A.
.BB.
.AA.
BBAA
....
....
Sie könnten auch tun:
A...
AA..
.B..
.BB.
.AB.
AABB
....
....
Fall 3
Eingang
#....#
######
.####.
.####.
Ausgabe
2
Erläuterung
A....B
AAABBB
.ABBB.
.AAAB.
(Dieser Testfall zeigt die Notwendigkeit, Formen für eine optimale Ausgabe zu drehen / reflektieren.)
Fall 4
Eingang
.###.
..#..
.##..
.##..
Ausgabe
2
Erläuterung
Unabhängig davon, wie Sie Blöcke auswählen, verhindert die Auswahl eines 2x1 aus der ersten Form zwangsläufig, dass die beiden anderen zusammen gruppiert werden. Somit können Sie eine 2x1 und zwei 1x1 verwenden. Allerdings (danke @Jonah) können Sie es in eine 3-Block-L-Form und ein einzelnes Quadrat wie folgt aufteilen:
.AAB.
..A..
.AA..
.BA..
Antworten:
Python 3.6 ,
799791 Bytes7 Bytes gespeichert von Jonathan Frech und motavica
Probieren Sie es online aus!
Verwendungszweck
A(s, t)
nimmt zwei Formen an, wobei jede Form durch eine Liste vonx, y
Gitterpositionen gegeben ist.Eine Hilfsfunktion zum Konvertieren der grafischen Darstellung in eine Liste von Positionen finden Sie unten:
Beispiel:
Erläuterung
Der hier verwendete Algorithmus ist etwas besser als Brute Force durch Zwischenspeichern von Unterformen. Für eine bestimmte Form werden alle Möglichkeiten zwischengespeichert, um diese Form in zwei zusammenhängende Formen aufzuteilen. Anschließend normalisiere ich diese Formen (verschiebe die Koordinaten so, dass sie am Ursprung beginnen, und finde dann eine Drehung / Reflexion davon, die im Cache verwendet wird). und speichern Sie sie im Cache, um später schnell nachzuschlagen. Bei allen Unterformen werden dann auch ihre Unterformen zwischengespeichert, bis die Einzelblockform erreicht ist.
Diese Unterformen werden generiert, indem sie in eine Diagramm-Adjazenzliste konvertiert und mithilfe eines BFS alle Untergraphen generiert werden. Wir können diese Untergraphen dann nach solchen filtern, bei denen die nicht enthaltenen Scheitelpunkte eine verbundene Komponente sind. Das Bestimmen, ob das Diagramm verbunden ist, erfolgt mit einem anderen BFS.
Nachdem der Cache vollständig ist, wird die Lösung gefunden, indem die beiden Formen verglichen werden, um die gemeinsamen Unterformen zu finden. Sobald diese Liste von Unterformen vorhanden ist, wird das nach dem Entfernen der gemeinsamen Form verbleibende Paar von Unterformen verwendet und derselbe Algorithmus erneut rekursiv angewendet, um die Mindestanzahl von Blöcken zu ermitteln, die zur Rekonstruktion der Form erforderlich sind. Dies gibt dann die Unterform mit dem Minimum all dieser Werte zurück und wir haben unsere Lösung.
Ich habe unten eine kommentierte Version eingefügt, um zu erklären, was jede Zeile tut.
quelle
if s==t else
könnte möglicherweise rückgängig gemacht werden, so dass der Ersatz von!=
to möglich ist^
.if i<len(s)-1else
~>if-~i<len(s)else
.def A(s,t):U(s);U(t);return V(P(s),P(t))
könnte möglicherweiselambda s,t:U(s)or U(t)or V(P(s),P(t))
drei Bytes sparen.s.union(*[g[n]for n in s])
~>s.union(*map(g.get,s))