Considérez la question 1C de Google Code Jam suivante :
La Grande Muraille de Chine commence comme une ligne infinie, où la hauteur à tous les endroits est de .
Certains nombre de tribus , N ≤ 1000 , va attaquer la paroi de la paroi en fonction des paramètres suivants : - une date de début, D , une résistance de démarrage S , un ouest coordonnée départ, W , et un départ est coordonnée, E . Cette première attaque se produit au jour D , sur la gamme [ W , E ] , à force S . S'il y a une partie de la Grande Muraille dans [ W , E ] qui a une hauteur < S, l'attaque est réussie, et à la fin de la journée, le mur sera construit de telle sorte que tout segment de celui-ci à l'intérieur de hauteur < S serait alors à la hauteur S (ou plus, si une autre attaque ce jour-là a frappé le même segment avec la force S ′ > S )
Chaque tribu effectuera jusqu'à attaques avant de battre en retraite, et chaque attaque sera déterminée de manière itérative par rapport à celle qui la précède. Chaque tribu a des δ D , δ X et δ S qui déterminent leur séquence d'attaques: ils attendront δ D ≥ 1 jours entre les attaques, ils déplaceront leur portée d'attaque de δ X unités pour chaque attaque (négatif = ouest, positif = est), bien que la taille de la portée reste la même et que leur force augmente / diminue également d'une valeur constante après chaque attaque.
Le but du problème est, étant donné une description complète des tribus attaquantes, de déterminer combien de leurs attaques réussiront.
J'ai réussi à coder une solution qui fonctionne, en environ 20 secondes: je crois que la solution que j'ai implémentée prend , où A = le nombre total d'attaques dans une simulation (max 1000000 ) et X = le nombre total de points de bord uniques sur les plages d'attaque (max 2000000 ).
À un niveau élevé, ma solution:
- Lit toutes les informations sur la tribu
- Calcule toutes les coordonnées uniques pour les plages d'attaque - O ( A )
- Représente le mur comme un arbre binaire mis à jour paresseusement sur les plages qui suit les valeurs de hauteur minimale. Une feuille est l'étendue de deux coordonnées X sans rien entre les deux, et tous les nœuds parents représentent l'intervalle continu couvert par leurs enfants. - O ( X log X )
- Génère toutes les attaques que chaque tribu effectuera et les trie par jour -
- Pour chaque attaque, voyez si elle réussira ( heure de requête ). Lorsque le jour change, parcourez toutes les attaques réussies non traitées et mettez à jour le mur en conséquence ( enregistrez l' heure de mise à jour X pour chaque attaque). - O ( A log X )
Ma question est la suivante: existe-t-il un moyen de faire mieux que ? Peut-être existe-t-il un moyen stratégique de tirer parti de la nature linéaire des attaques successives des Tribus? 20 secondes semble trop long pour une solution envisagée (bien que Java puisse être à blâmer pour cela).