Le défi
Il y a N villes alignées en ligne droite. La i-ème ville est située à quelques A[i]
kilomètres à droite de l'origine. Il n'y aura pas deux villes au même endroit.
Vous allez construire un réseau électrique avec quelques centrales électriques. Les centrales électriques doivent être construites à l'intérieur d'une ville. Cependant, vous n'êtes autorisé qu'à construire K
(<N) des centrales électriques, il y aura donc certaines villes sans centrale électrique. Pour chaque ville sans centrale électrique, vous devez construire un câble entre elle et la ville la plus proche qui a une centrale électrique .
Par exemple, s'il y a trois villes situées à 0, 1, 2
, et que seule la ville de 0
possède une centrale électrique, vous devez construire deux câbles, l'un de 2
à 0
(2 km) et l'autre de 1
à 0
(1 km), qui ont une longueur totale de 3 km .
Étant donné K
et les positions des villes ( A
), vous devez calculer les kilomètres minimum de câble dont vous avez besoin pour construire le réseau.
Exemples de tests
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
Caractéristiques
Vous devez implémenter une fonction ou un programme, qui prend un entier positif
K
et une liste d'entiersA
sous n'importe quelle forme, et produire / renvoyer un entier représentant la réponse.A
est trié par ordre croissant et tous les éléments sont des entiers non négatifs.A[0] = 0
, etA[N-1]
ne dépassera pas 1000N.Notez que la sortie sera d'une magnitude de 1000N 2 , donc dans les cas plus importants, vous aurez peut-être besoin d'entiers 64 bits dans certaines langues.
Le multithreading n'est pas autorisé (je définirai l'affinité de votre programme à seulement 1 noyau lors du jugement). Les optimisations du compilateur (comme
-O2
en C) sont autorisées.
Notation
Je chronométrerai votre code sur mon ordinateur (Ubuntu 16.04 avec processeur Intel i7-3770S) avec différentes tailles de tests. Plus précisément, je vais générer des cas de test avec N = plancher (2 x / 5 ) où x est un entier positif.
Votre score sera la valeur x du plus petit cas de test que votre programme utilise plus de 10 secondes ou 1 Gio de mémoire, ou ne donne pas une réponse correcte.- La réponse avec le score le plus élevé l'emporte. Si deux réponses obtiennent le même score, la réponse précédente l'emporte.
Tous les programmes seront jugés par le même ensemble de tests.
N'hésitez pas à poster vos propres scores. Les explications de votre algorithme sont encouragées.
Prime
Ceci est mon programme C ++, il obtient 108 . Vous pouvez vérifier le résumé SHA-256 9a87fa183bad1e3a83d2df326682598796a216b3a4262c32f71dfb06df12935d
par le segment de code entier (sans pied de page) dans le lien.
L'algorithme combine la recherche binaire et l'optimisation de Knuth pour trouver la pénalité correcte de chaque plante pour obtenir le nombre souhaité. La complexité est O (N log N log A [N-1]). J'ai été surpris que le programme ait obtenu un score plus élevé que la solution O (N log A [N − 1]) d'Anders Kaseorg . C'est probablement dû au fait que le cas de journal dans l'optimisation de Knuth ne se produira généralement pas.
Notez que ce défi est le même que celui du bureau de poste IOI 2000 . Les contraintes d'origine sont cependant N <= 300 et K <= 30.
la source
2^^(x/5)
: quel est le sens ? pouvez-vous simplement fournir une limite supérieure pour N?N=21( = floor(2^(22/5)) )
en 10 secondes, mais ne peut pas gérerN=24( = floor(2^(23/5)) )
, alors 23 sera le score. Je n'ai pas utilisé de limite supérieure, car les différences entre les différents algorithmes sont trop importantes. Par exemple, si je mets N <= 40, il y aura peu de différence entreO(KN^2)
etO(KN^3)
, maisO(2^N)
ne se terminera même pas dans un temps résonable.Réponses:
Rouille , score = 104
Il s'agit d'une implémentation de l'algorithme noté par Grønlund et al. (2017) à la fin du §3.3.1, même si j'ai dû suivre une longue chaîne de citations et remplir certains détails manquants. Il fonctionne en O ( N log A [ N - 1]).
Compilez avec
rustc -O
. Le format d'entrée estK
sur la première ligne, suivi des entrées deA
, une entrée par ligne, toutes sur stdin.(Remarque: je soumets ceci une heure après la date limite de la prime, mais je m'attends à la dernière version que j'ai soumise avant la date limite de la prime , qui s'exécutait en O ( N log N log A [ N - 1]), marque environ 94 .)
Essayez-le en ligne!
Rouille , score pré-test = 73
Compilez avec
rustc -O
. Le format d'entrée estK
sur la première ligne, suivi des entrées deA
, une entrée par ligne, toutes sur stdin.Essayez-le en ligne!
la source
61
, mais c'est à cause du débordement deu32
. Vous pouvez peut-être passer au type entier 64 bits?type Cost = u32
pourtype Cost = u64
?73
.C, score = 56
contenu de
a.c
:script shell pour compiler et tester ce qui précède:
n = 776 prend 6,2 s, n = 891 prend 12 sn = 1176 prend 5,9s, n = 1351 prend un peu plus de 10sn = 1351 prend 8,7 s, n = 1552 prend plus de 10 s (avec k = 2 * n / 3) sur mon
Intel(R) Core(TM) i3-2375M CPU @ 1.50GHz
la source
syntax/c.vim
.C ++, score = 53
La solution que j'avais dit dans le commentaire.
O(n²×k)
. (maintenant je l'ai supprimé car il n'est plus nécessaire) Peut probablement être réduit àO(n×k)
.L'entrée est assez flexible, sur la première ligne, le premier nombre est
k
, les autres nombres sont des éléments du tableaua
, mais s'il rencontre des parenthèses fermées, il arrête de lire l'entrée. Donc, la saisie commeK = 1, A = [0, 2, 4, 6, 8] : 12
est acceptée.Essayez-le en ligne!
Générez des cas de test aléatoires. (entrée
N
et éventuellement plage de villes,1000×N
par défaut)la source
int
s nécessaires enint64_t
s.C #, score = 23
Je suis sûr que cela ne va pas gagner ce défi, je voulais juste poster une première réponse (et très basique) pour encourager d'autres personnes à poster leurs algorithmes et à améliorer les miens. Ce code doit être compilé en tant que projet de console qui utilise le package Combinatorics de NuGet. La méthode principale contient quelques appels à la
Build
méthode pour tester les cas proposés.Explication vraiment simple: pour chaque combinaison
c
d'k
éléments dea
, calculer la somme des distances de chaque élément dea
l'élément le plus proche dansc
, et renvoyez la combinaison avec la distance totale la plus faible.Version à une ligne de la
Build
méthode (probablement plus lente que la version originale développée; il faut y ajouter une référenceSystem.Linq
):la source
C ++, score = 48
Entrée d'utilisation: NKA [1] A [2] ... A [N]
la source
step
70, alors votre score de prétest est de 60.Ruby , score = 23
Essayez-le en ligne!
Je ne pense pas que ça va gagner, mais je voulais essayer.
la source
JavaScript (ES6) (Node.js) , score = 10
Nouvel algorithme, expliquera si cela fonctionne réellement cette fois.
Essayez-le en ligne!
Exécutez la même manière que l'autre.
JavaScript (ES6) (Node.js) , score de prétest = 12
Aperçu de l'algorithme:
Le programme mappe d'abord les données dans la classe City, qui mappe quelques points de données:
le tableau est ensuite jeté dans la classe Group, qui présente les éléments suivants:
Maintenant, l'algorithme continue de diviser les groupes tant qu'il a 2 centrales électriques ou plus à placer.
Enfin, il mappe les groupes aux centres it et les résume tous.
Comment exécuter:
Exécuter en utilisant Node.js (v9.2.0 est ce qui a été utilisé pour la création)
exécuter le programme en utilisant des cas de test générés pour le score 70:
gérer le programme en utilisant 1 centrale électrique et des villes [0,3,5]:
Code:
Essayez-le en ligne!
Je vais nettoyer le code commenté au cours des prochains jours car je travaille toujours sur cela, je voulais juste voir si cela passait plus que les petits cas.
la source
K = 2, A = [0, 21, 31, 45, 49, 54]
. La bonne réponse est 40, mais votre programme affiche 51.K = 2, A = [0, 4, 7, 9, 10]
. Correct: 7, votre réponse: 8.K = 2, A = [0, 1, 3, 4, 9]
. Correct: 6, votre réponse: 7.C (non compétitif, score pré-test = 76)
Il s'agit d'une tentative de traduire la deuxième solution Rust de @ AndersKaseorg en C.
Compiler avec:
la source
Propre , score = 65
Compiler avec:
clm -h 1024M -gci 32M -gcf 32 -s 32M -t -nci -ou -fusion -dynamics -IL Platform main
Prend
K
, puis chaque élément deA
, comme arguments de ligne de commande.la source