Advertisement
Guest User

Untitled

a guest
Jan 30th, 2018
1,239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.12 KB | None | 0 0
  1. LogoFrance-IOI
  2. France-IOI » Courses and tasks » Efficacité temporelle » Premier absent
  3. fedi37
  4. See my public page
  5. My profile
  6. Authentication
  7. Log out
  8. Language: English
  9. Sitemap
  10. Improving
  11. Presentation
  12. Courses and tasks
  13. Frequent questions
  14. Help forum
  15. Teaching
  16. Presentation
  17. Groups and classes
  18. Competing
  19. Presentation
  20. Ranking
  21. Contest tasks
  22. Results
  23. Olympiads
  24. Presentation
  25. Selection
  26. Results
  27. Other Olympiads
  28. The association
  29. Presentation
  30. History
  31. Training camps
  32. Contact us
  33. Report a bug
  34. 225 users online
  35. Demands for help
  36. today
  37. domino
  38. Distributeur automatique
  39. today
  40. calusrel
  41. Maison de l'espion
  42. today
  43. mamous 2021
  44. Tours de Hanoï
  45. yest.
  46. marie974 2017
  47. La bataille
  48. d.
  49. kamikadze 2020
  50. Nombre d'amour
  51. Successful submissions
  52. 16:08
  53. haonam 2015
  54. Tri des données
  55. 16:08
  56. thefrenchmonster
  57. Encore des punitions
  58. 16:08
  59. nathan-rorby 2017
  60. Villes et villages
  61. 16:07
  62. mestre-maiwenn 2020
  63. Transport d'eau
  64. 16:07
  65. melyna 2020
  66. Course avec les enfants
  67. 16:07
  68. benjaminolivier 2020
  69. Course avec les enfants
  70. 16:07
  71. vtcba
  72. Mathématiques de base
  73. 16:07
  74. skrempp 1997
  75. Résumés de livres
  76. 16:07
  77. sarkozy 2020
  78. Graduation de thermomètres
  79. 16:07
  80. miroineau 2020
  81. Visite de la mine
  82. 16:06
  83. calusrel
  84. Amitié entre gardes
  85. 16:06
  86. bast29 2020
  87. Mont Kailash
  88.  
  89. C++
  90. Validé !Premier absent
  91. Print
  92. TaskSolveHelpActivitySolution
  93. Jacques-Henri Jourdan
  94.  
  95. Solution naïve
  96. On peut stocker dans une liste l'ensemble des élèves déjà arrivés. Pour implémenter cette liste, on peut par exemple utiliser un tableau, qui contient, dans les premières cases, les élèves déjà arrivés. À chaque fois qu'un nouvel élève arrive, on peut recalculer le premier élève absent : il va donc faloir tester, pour chaque élève inscrit, s'il est présent.
  97.  
  98. Il y a nbPrésents arrivées de nouveaux élèves, et à chaque fois, a priori, il faut vérifier nbInscrits élèves inscrits. De plus, la vérification de la présence d'un élève se fait en nbPrésents étapes. Au total, la compexité est de O(nbInscrits*nbPrésents^2).
  99.  
  100. présents = liste vide
  101. Pour chaque présent de 0 à nbPresents-1
  102. Lire identifiant
  103. présents.ajouter(identifiant-1)
  104. Pour chaque inscrit de 0 à nbInscrits-1
  105. inscritEstAbsent = Faux
  106. Pour chaque élève dans présents
  107. Si élève == inscrit
  108. inscritEstAbsent = Vrai
  109. Sortir de la boucle
  110. Si inscritEstAbsent
  111. Afficher inscrit
  112. Sortir de la boucle
  113. Si aucun absent n'a été trouvé
  114. tous les élèves sont présents
  115. On peut faire une meilleure analyse de la complexité : en effet, l'identifiant du premier élève absent sera toujours plus petit ou égal au nombre d'élèves présents. Ainsi, la boucle qui teste tous les élèves inscrits et qui vérifie s'il est présent n'effectue en fait dans le pire cas que O(nbPrésents) itérations. La complexité devient alors O(nbPrésents^3), ce qui est trop lent.
  116.  
  117. Meilleure structure de données
  118. Dans la solution précédente, une opération qui prend du temps est de tester si un élève donné est présent. Il existe plusieurs structures de données qui permettent de répondre à ce type de question efficacement. Ici, on peut par exemple utiliser un tableau à accès direct : dans chaque case du tableau, on met Vrai si l'élève est déjà arrivé, Faux sinon.
  119.  
  120. élèvesArrivés = tableau à nbInscrit cases, remplies à Faux
  121. Pour chaque présent de 0 à nbPresents-1
  122. Lire identifiant
  123. élèvesArrivés[identitifant-1] = Vrai
  124. Pour chaque inscrit de 0 à nbInscrits-1
  125. Si non élèvesArrivés[inscrit]
  126. Afficher inscrit
  127. Sortir de la boucle
  128. Si aucun absent n'a été trouvé
  129. tous les élèves sont présents
  130. L'accès à la table se fait en O(1), et l'algorithme a donc une complexité de O(nbPrésents^2). Par contre, la complexité en mémoire est moins bonne : elle est en O(nbInscrits). Le sujet du problème indique que seuls 5000 Ko sont disponibles pour résoudre ce prolème. En supposant que l'on stocke un booléen sur un octet, nbInscrits ne pourra jamais dépasser 5 000 000.
  131.  
  132. Pour éviter le problème de mémoire, on peut utiliser une deuxième fois le fait que l'identifiant du premier élève absent est plus petit ou égal au nombre d'élèves présents. On voit donc qu'il suffit de prendre un tableau de taille nbPrésents+1.
  133.  
  134. élèvesArrivés = tableau à nbPrésents+1 cases, remplies à Faux
  135. Pour chaque présent de 0 à nbPresents-1
  136. Lire identifiant
  137. Si identifiant < nbPrésents
  138. élèvesArrivés[identitifant] = Vrai
  139. Pour chaque inscrit de 0 à nbInscrits-1
  140. Si non élèvesArrivés[inscrit]
  141. Afficher inscrit
  142. Sortir de la boucle
  143. Si aucun absent n'a été trouvé
  144. tous les élèves sont présents
  145. La complexité en mémoire devient O(nbPrésents). Cependant, la complexité en temps reste O(nbPrésents^2), ce qui est trop lent vu les contraintes du sujet.
  146. Solution finale
  147. On remarque que l'identifiant du premier élève absent ne fait qu'augmenter. Aussi, il n'est pas nécessaire de tester la présence d'élèves qui ont déjà été testés comme présent à une itération précédente.
  148.  
  149. élèvesArrivés = tableau à nbPrésents+1 cases, remplies à Faux
  150. premierAbsent = 0
  151. Pour chaque présent de 0 à nbPresents-1
  152. Lire identifiant
  153. Si identifiant < nbPrésents
  154. élèvesArrivés[identitifant] = Vrai
  155. Tant que premierAbsent < nbInscrits et élèvesArrivés[premierAbsent]
  156. premierAbsent++
  157. Si premierAbsent < nbInscrits
  158. Afficher premierAbsent
  159. Sinon
  160. tous les élèves sont présents
  161. La variable premierAbsent ne peut être incrémentée que O(nbPrésents) fois. Le nombre d'itérations total effectué par le corps de la boucle Tant que est donc O(nbPrésents). La complexité de l'algorithme est donc O(nbPrésents) en temps et en mémoire.
  162.  
  163. Code C++
  164. #include<cstdio>
  165.  
  166. bool presents[250 * 1000 + 1];
  167.  
  168. int main(){
  169. int nb_presents, nb_eleves;
  170. scanf("%d%d", &nb_eleves, &nb_presents);
  171. int premier_absent = 0;
  172. for(int present = 0; present < nb_presents; present++)
  173. {
  174. int id;
  175. scanf("%d", &id);
  176. id--;
  177. if(id < nb_presents)
  178. presents[id] = true;
  179.  
  180. while(premier_absent < nb_eleves && presents[premier_absent])
  181. premier_absent++;
  182.  
  183. if(premier_absent == nb_eleves)
  184. printf("-1\n");
  185. else
  186. printf("%d\n", premier_absent + 1);
  187. }
  188.  
  189. return 0;
  190. }
  191. Code Caml
  192. let scan_int () = Scanf.scanf " %d" (fun x -> x)
  193. let show_int n = Printf.printf "%d\n" n
  194. let nb_eleves = scan_int()
  195. let nb_presents = scan_int()
  196.  
  197. let presents = Array.make (nb_presents+1) false
  198. let premier_absent = ref 1
  199.  
  200. let _ =
  201. for present = 1 to nb_presents do
  202. let id_eleve = scan_int() in
  203.  
  204. if id_eleve < nb_presents
  205. then presents.(id_eleve) <- true;
  206.  
  207. while !premier_absent < nb_eleves && presents.(!premier_absent) do
  208. incr premier_absent
  209. done;
  210.  
  211. if !premier_absent = nb_eleves
  212. then show_int (-1)
  213. else show_int (!premier_absent)
  214. done
  215. Validé !Premier absent
  216. Print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement