<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Complexité algorithmique</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Notion de complexité asymptotique, notation O, classes<br/>
classiques (constante, logarithmique, linéaire, quasi<br/>
linéaire, quadratique, exponentielle), calcul à partir<br/>
du code, comparaison expérimentale, échelle de<br/>
croissance.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q01 : Définition de la complexité</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que mesure la <strong>complexité algorithmique</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux types de complexité : <strong>temporelle</strong> (nombre<br/>
d'opérations) et <strong>spatiale</strong> (mémoire utilisée).<br/>
En NSI Première, on s'intéresse surtout à la<br/>
complexité temporelle.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le nombre de lignes de code source nécessaires pour écrire l'algorithme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la complexité algorithmique mesure<br/>
l'évolution des <strong>ressources</strong> (temps,<br/>
mémoire), pas la longueur du code.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La quantité de ressources consommée selon la taille de l'entrée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on étudie comment le coût<br/>
(temps de calcul, mémoire) évolue lorsque la<br/>
taille n de l'entrée grandit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le temps d'exécution en secondes, mesuré sur une machine donnée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la complexité ne dépend ni de la<br/>
machine ni du langage. Elle compte des<br/>
opérations élémentaires en fonction de la<br/>
taille n, pas des secondes sur un ordinateur<br/>
particulier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La difficulté qu'a un lecteur humain à comprendre le code source</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est la « complexité cognitive », notion<br/>
différente, non quantifiée formellement en<br/>
NSI.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q02 : Notation O</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que signifie l'écriture <code>O(n)</code> (« grand O de n ») ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>O(n) caractérise une famille de fonctions qui<br/>
croissent au plus comme c × n pour une constante<br/>
c. C'est une notation d'ordre de grandeur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme effectue exactement <code>n</code> opérations</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>O(n)</code> est une borne <strong>asymptotique</strong>,<br/>
pas un compte exact. L'algorithme peut faire<br/>
<code>2n + 5</code> opérations, on note <code>O(n)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le nombre d'opérations croît proportionnellement à n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : O(n) signifie « linéaire ».<br/>
Doubler n double approximativement le temps.<br/>
Les constantes et les termes d'ordre<br/>
inférieur sont ignorés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme utilise exactement n octets de mémoire vive</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>O(n) peut s'appliquer à la mémoire, mais ce<br/>
n'est pas une définition générale.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'algorithme se termine en moins de n secondes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : O ne mesure pas un temps absolu mais<br/>
une <strong>proportion</strong>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q03 : Classes classiques</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les complexités suivantes, laquelle est la<br/>
<strong>plus rapide</strong> asymptotiquement ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Hiérarchie classique (du plus rapide au plus<br/>
lent) : O(1) &lt; O(log n) &lt; O(n) &lt; O(n log n) &lt;<br/>
O(n²) &lt; O(n³) &lt; O(2ⁿ) &lt; O(n!).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : quadratique, l'une des plus lentes<br/>
dans cette liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne, mais pas la plus rapide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : logarithmique. Pour n = 10⁶,<br/>
log₂(n) ≈ 20. C'est la complexité de la<br/>
recherche dichotomique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Linéaire : plus rapide que quadratique mais<br/>
plus lente que logarithmique.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q04 : Boucle simple</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de cette fonction en<br/>
fonction de <code>n = len(liste)</code> ?<br/>
<pre><code>def somme(liste):
    total = 0
    for x in liste:
        total += x
    return total</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle pratique : une boucle imbriquée 0 fois<br/>
→ O(1) ; 1 fois → O(n) ; 2 fois → O(n²) ; etc.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun mécanisme dichotomique ici.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle dépend de la taille de<br/>
la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : une boucle simple sur n<br/>
éléments avec une opération constante par<br/>
itération donne O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pas de double boucle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q05 : Double boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de cette fonction ?<br/>
<pre><code>def doublons(liste):
    n = len(liste)
    for i in range(n):
        for j in range(n):
            if i != j and liste[i] == liste[j]:
                return True
    return False</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux boucles imbriquées donnent O(n²). Astuce :<br/>
on peut faire mieux ici en O(n) avec un seul<br/>
parcours qui note dans un dictionnaire les<br/>
valeurs déjà vues, car le test <code>x in vues</code> sur<br/>
les clés d'un dictionnaire est en O(1) en<br/>
moyenne.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le <code>for j in range(n)</code> imbriqué<br/>
ajoute un facteur n.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : double boucle, donc dépend de n.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n!)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : factorielle, c'est la complexité<br/>
d'algorithmes énumérant toutes les<br/>
permutations.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : deux boucles imbriquées sur<br/>
n éléments donnent n × n = n² opérations<br/>
au pire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q06 : Constante</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de l'accès <code>liste[i]</code><br/>
sur une <strong>liste Python</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinguer : <code>liste[i]</code> est en O(1) ;<br/>
<code>cible in liste</code> est en O(n) ; <code>liste.append(x)</code><br/>
est en O(1) en moyenne ; insérer un élément en<br/>
tête de liste, en revanche, oblige à décaler<br/>
tous les autres et coûte O(n).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un accès par indice est trivial.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune dichotomie nécessaire,<br/>
accès direct.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour une <code>list</code> Python, l'accès par<br/>
indice est immédiat, on n'a pas besoin de<br/>
parcourir la liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les listes Python sont des<br/>
tableaux, l'accès par indice est en temps<br/>
constant indépendamment de la taille.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q07 : Taille de l'entrée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour une liste, qu'est-ce que la « taille de<br/>
l'entrée » <code>n</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Selon le contexte, la « taille » peut être<br/>
différente : nombre de chiffres pour un entier,<br/>
nombre de pixels pour une image, nombre de lignes<br/>
pour un fichier, etc.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le numéro de ligne où la liste est définie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le numéro de ligne du<br/>
code source ne joue<br/>
aucun rôle dans le coût<br/>
d'exécution. La taille<br/>
d'entrée caractérise le<br/>
volume de données traité,<br/>
ici le nombre d'éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur du plus grand élément</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la complexité ne dépend<br/>
généralement pas des <strong>valeurs</strong>, mais de<br/>
la <strong>structure</strong>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La quantité de mémoire qu'elle occupe en octets</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est lié, mais pas la définition standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le nombre d'éléments de la liste (sa longueur)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la taille pertinente pour<br/>
la complexité d'une liste est sa longueur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q08 : Pire / moyen / meilleur cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi distingue-t-on <strong>pire cas, cas moyen, meilleur cas</strong> dans l'analyse de complexité ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>En général, on retient le <strong>pire cas</strong> comme<br/>
référence : il garantit qu'au-delà, le coût ne<br/>
dépassera pas. Le cas moyen est utile pour<br/>
l'analyse fine en pratique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour pouvoir annoncer la complexité la plus avantageuse</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on ne choisit pas le cas qui<br/>
arrange. En pratique, on retient le<br/>
<strong>pire cas</strong>, car il fournit une<br/>
garantie valable pour toutes les<br/>
entrées possibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les langages de programmation diffèrent</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Sans rapport : la complexité est<br/>
intrinsèque à l'algorithme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que la complexité peut dépendre du contenu, pas seulement de la taille</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour le tri par insertion,<br/>
une liste déjà triée donne O(n), une liste<br/>
renversée donne O(n²). Le pire cas est le<br/>
plus important pour les garanties.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le résultat renvoyé change selon les données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : confusion entre coût et<br/>
correction. Un algorithme correct<br/>
renvoie le bon résultat dans tous<br/>
les cas ; ce qui varie d'un cas à<br/>
l'autre, c'est le <strong>nombre<br/>
d'opérations</strong> effectuées, pas le<br/>
résultat.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q09 : Échelle de croissance</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour n = 1000, qui est le plus grand ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Échelle pour n = 1000 : log n = 10, n = 10³,<br/>
n² = 10⁶, 2ⁿ ≈ 10³⁰¹. Différence colossale.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : n = 1000 = 10³, valeur<br/>
intermédiaire parmi les quatre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>2ⁿ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : 2¹⁰⁰⁰ ≈ 10³⁰¹, un nombre de<br/>
plus de 300 chiffres, astronomiquement plus<br/>
grand que 10⁶ ou 10³. C'est pourquoi on<br/>
évite à tout prix les algorithmes<br/>
exponentiels sur de grandes entrées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>n²</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : n² = 10⁶, c'est grand mais très<br/>
loin derrière l'exponentielle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>log₂(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : log₂(1000) ≈ 10, c'est la valeur<br/>
la plus petite des quatre.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q10 : Recherche</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de la <strong>recherche dichotomique</strong> dans une liste triée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Hiérarchie classique : O(log n) (dichotomie)<br/>
&lt;&lt; O(n) (parcours simple) &lt;&lt; O(n²) (double<br/>
parcours) &lt;&lt; O(2ⁿ) (énumération exponentielle).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est la recherche <strong>linéaire</strong>,<br/>
pas dichotomique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : à chaque étape, on divise<br/>
la liste en deux. C'est la complexité de<br/>
référence pour les algorithmes de<br/>
dichotomie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun double parcours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on doit comparer plusieurs<br/>
éléments dans le pire cas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q11 : Boucles imbriquées</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de :<br/>
<pre><code>for i in range(n):
    for j in range(n):
        for k in range(n):
            print(i, j, k)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle simple : pour des boucles imbriquées<br/>
sur n, la complexité est n^(profondeur).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trois boucles imbriquées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est deux boucles imbriquées,<br/>
pas trois.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(3n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait trois boucles <strong>non imbriquées</strong>, soit O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n³)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : trois boucles imbriquées<br/>
sur n donnent n × n × n = n³ opérations.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q12 : Deux boucles séparées</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de :<br/>
<pre><code>for i in range(n):
    print(i)
for j in range(n):
    print(j)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle : O(f) + O(g) = O(max(f, g)). La<br/>
complexité d'une séquence est dominée par sa<br/>
partie la plus coûteuse.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(2)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le coût dépend de n.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les boucles ne sont <strong>pas imbriquées</strong>, on les additionne, on ne les<br/>
multiplie pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : n + n = 2n opérations, et 2n<br/>
est un O(n), les constantes sont absorbées.<br/>
On n'écrit jamais O(2n), seulement O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune division du problème ni tri<br/>
ici, seulement deux parcours successifs de n<br/>
tours. Le total vaut 2n, c'est un O(n).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q13 : Termes dominants</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de l'expression<br/>
<code>T(n) = 3n² + 100n + 50</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle systématique : ne garder que le terme<br/>
le plus puissant et supprimer la constante<br/>
multiplicative. C'est l'essence de la notation<br/>
asymptotique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(3n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on n'écrit pas la constante<br/>
multiplicative dans la notation O.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le terme <strong>dominant</strong> pour<br/>
n grand est <code>3n²</code>. Les autres termes (100n,<br/>
50) deviennent négligeables.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(50)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 50 est une constante mais elle est<br/>
dominée par les termes en n.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(100n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on n'écrit pas la constante. De<br/>
plus, c'est dominé par n².</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q14 : Doublement de la taille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un algorithme en O(n²) traite n = 1000<br/>
éléments en 1 seconde. Combien de temps lui<br/>
faudra-t-il pour n = 2000 ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compétence essentielle : extrapoler le temps<br/>
d'exécution. Cela permet d'<strong>anticiper</strong> si un<br/>
algorithme va supporter la charge.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1 seconde (le temps ne change pas)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait O(1).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>4 secondes (n doublé → temps quadruplé)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : O(n²) signifie temps ∝ n².<br/>
Multiplier n par 2 multiplie le temps par 4<br/>
(= 2²). Doubler n multiplierait par 4, tripler par 9.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>1000 secondes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Surestimation grossière.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>2 secondes (n doublé → temps doublé)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait O(n).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q15 : Pire vs meilleur cas</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La recherche linéaire est en <code>O(n)</code> au pire et<br/>
<code>O(1)</code> au meilleur. Que dire si l'on parle de<br/>
« complexité » sans précision ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le pire cas a une signification claire et<br/>
garantit la performance « au pire ». Le cas<br/>
moyen demanderait de modéliser la<br/>
distribution de probabilité des entrées.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On parle du cas moyen</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas la convention standard, sauf<br/>
précision.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On parle implicitement du meilleur cas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : par convention, on prend le pire<br/>
cas si rien n'est précisé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>On parle du cas le plus probable</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas une notion bien définie sans modèle<br/>
probabiliste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>On parle implicitement du pire cas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est la convention en NSI<br/>
et plus largement. Le pire cas garantit<br/>
une borne supérieure.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q16 : Créer une grille n × n</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On crée une grille de $n$ lignes et $n$ colonnes remplie de zéros :</p>
<pre><code>grille = [[0 for j in range(n)] for i in range(n)]</code></pre>
<p>Quel est le coût de cette instruction en fonction de $n$ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une compréhension cache une boucle. Deux compréhensions imbriquées se<br/>
comptent comme deux boucles imbriquées : $n \times n$ opérations, soit<br/>
un coût quadratique. Pour $n = 1\,000$, cela fait déjà un million de<br/>
cases.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'instruction tient sur une ligne, mais elle contient deux<br/>
boucles imbriquées. Chacune des $n$ lignes demande elle-même $n$<br/>
opérations.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(1)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une seule instruction ne signifie pas un coût constant.<br/>
Créer $n^2$ cases demande un travail qui grandit avec $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n^2)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la compréhension externe fait $n$ tours et chacun<br/>
construit une ligne de $n$ zéros par la compréhension interne.<br/>
Cela fait $n \times n = n^2$ cases à remplir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(2n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux compréhensions ne se suivent pas, elles sont<br/>
imbriquées : on multiplie leurs nombres de tours au lieu de les<br/>
additionner, ce qui donne $n^2$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q17 : Fusionner deux tables</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour fusionner une table d'élèves et une table de notes, chacune de<br/>
$n$ lignes, on écrit :</p>
<pre><code>def fusion(eleves, notes):
    resultat = []
    for e in eleves:
        for x in notes:
            if e["nom"] == x["nom"]:
                resultat.append({"nom": e["nom"], "classe": e["classe"], "note": x["note"]})
    return resultat</code></pre>
<p>Quel est le coût de <code>fusion</code> en fonction de $n$ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Fusionner deux tables par deux boucles imbriquées coûte $n^2$<br/>
comparaisons. Sur de grandes tables, ce coût devient vite<br/>
prohibitif ; trier la table des notes par nom permettrait de<br/>
chercher chaque élève par dichotomie.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(2n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux tables ne sont pas parcourues l'une après<br/>
l'autre, mais l'une dans l'autre. Les nombres de tours se<br/>
multiplient, d'où $n^2$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n^2)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour chacune des $n$ lignes d'élèves, la boucle<br/>
interne parcourt les $n$ lignes de notes. Le test d'égalité des<br/>
noms est donc évalué $n \times n$ fois : $90\,000$ fois pour deux<br/>
tables de $300$ lignes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(\log n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune moitié de table n'est éliminée ici, les boucles<br/>
examinent toutes les lignes. Un coût logarithmique supposerait une<br/>
recherche dichotomique dans une table triée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n)$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : même si chaque élève n'a qu'une note, la boucle interne<br/>
ne s'arrête pas quand elle la trouve. Elle parcourt toute la table<br/>
des notes, pour chaque élève.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q18 : Algorithmes exponentiels</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi évite-t-on les algorithmes en O(2ⁿ) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un algorithme exponentiel sur n = 100 prendrait<br/>
des milliards d'années même sur le meilleur<br/>
ordinateur du monde. Pour ces problèmes, on<br/>
utilise des heuristiques ou des algorithmes<br/>
approchés.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'ils occupent trop de place sur le disque dur de la machine</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'espace de stockage n'est pas en cause :<br/>
c'est le temps de calcul qui devient<br/>
prohibitif.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'aucun problème concret ne conduit à un tel algorithme</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ils existent bel et bien, par<br/>
exemple pour énumérer tous les sous-ensembles<br/>
d'un ensemble de n éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que leur coût explose dès que n atteint quelques dizaines</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : pour n = 50, 2ⁿ ≈ 10¹⁵<br/>
opérations, hors d'atteinte même sur un<br/>
super-calculateur. La croissance<br/>
exponentielle rend l'algorithme impraticable<br/>
dès que n dépasse quelques dizaines.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce qu'ils résultent presque toujours d'une programmation maladroite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un algorithme exponentiel peut être<br/>
parfaitement écrit, c'est sa <strong>structure</strong><br/>
qui pose problème.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q19 : Estimer un temps</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un algorithme effectue 10⁹ opérations<br/>
élémentaires. Sur un PC moderne (environ 10⁹<br/>
opérations / seconde), combien de temps<br/>
attendra-t-on ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Repère mental : 10⁸ par seconde en Python (un<br/>
peu lent), 10⁹ ou plus en C/C++. Permet<br/>
d'anticiper si un algorithme passera ou non<br/>
la contrainte de temps.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Environ une seconde</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : 10⁹ opérations à<br/>
environ 10⁹ opérations par seconde donnent<br/>
environ une seconde (et plutôt<br/>
quelques secondes en Python, qui<br/>
tourne autour de 10⁸ par seconde).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Plusieurs années</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : à 10⁹ opérations par seconde, une<br/>
année représente environ 3 × 10¹⁶<br/>
opérations. Plusieurs années correspondent<br/>
donc à environ 10¹⁷ opérations, très loin de 10⁹.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Plusieurs jours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une journée représente environ<br/>
10¹⁴ opérations à cette vitesse. Pour 10⁹<br/>
opérations, le calcul donne 10⁹ / 10⁹ = 1<br/>
seconde.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Quelques nanosecondes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : 10⁹ opérations à 10⁹/s = 1<br/>
seconde, pas une nanoseconde.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q20 : Petit vs grand n</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour n petit (n = 10), un algorithme O(n²) est-il<br/>
forcément moins efficace qu'un algorithme O(n) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>À retenir : la notation O décrit l'évolution du coût pour de<br/>
grandes tailles. Pour les petits n, des constantes plus petites<br/>
peuvent compenser un ordre de grandeur plus grand ; pour les<br/>
grands n, l'ordre de grandeur l'emporte.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun rapport entre ces deux complexités</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ces deux coûts se comparent bien ; pour de grandes<br/>
entrées, O(n) finit toujours par battre O(n²).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Oui, O(n²) est toujours moins efficace</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la notation O cache des<br/>
<strong>constantes</strong> qui peuvent renverser le<br/>
classement sur les petites entrées.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Non : sur les petites entrées, les constantes peuvent dominer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un algorithme qui fait exactement 100 × n<br/>
opérations est en O(n), un autre qui en fait n² est en O(n²).<br/>
Pour n = 10, le premier fait 1 000 opérations et le second<br/>
seulement 100.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Non, car pour n = 10 les deux donnent le même nombre d'opérations</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur de calcul : pour n = 10, n² vaut 100 alors que n vaut 10.<br/>
Les deux nombres d'opérations ne coïncident pas ; la vraie raison<br/>
est que la notation O cache des constantes multiplicatives qui<br/>
peuvent renverser le classement.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q21 : Analyse fine</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de :<br/>
<pre><code>def f(n):
    for i in range(n):
        for j in range(i):
            print(i, j)</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Astuce : même si la boucle interne ne va pas<br/>
jusqu'à n, la somme reste en n². Cas typique<br/>
des tris en O(n²).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle interne fait i<br/>
itérations. Total = 0 + 1 + ... + (n-1)<br/>
= n(n-1)/2 ≈ n²/2. C'est O(n²).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun mécanisme dichotomique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : double boucle.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n³)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : trois boucles imbriquées<br/>
donneraient n³.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q22 : Boucle qui divise</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une boucle parcourt une variable <code>n</code> en la<br/>
<strong>divisant par 2</strong> à chaque tour, jusqu'à<br/>
atteindre 1 (à chaque tour, travail<br/>
constant). Quel est le coût total ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Schéma caractéristique : à chaque itération,<br/>
la quantité de travail restant est divisée<br/>
par 2. Donne un coût logarithmique. C'est<br/>
l'analyse de la recherche dichotomique.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Quadratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun double parcours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Constant</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il y a plusieurs tours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Logarithmique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on passe de n à n/2 à n/4<br/>
à ... à 1, soit log₂(n) étapes. C'est<br/>
exactement le coût de la dichotomie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on divise par 2, pas par<br/>
soustraction de 1.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q23 : Doublons dans une liste triée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour savoir si une liste <strong>triée</strong> contient un doublon, on compare<br/>
chaque élément à son voisin :<br/>
<pre><code>def a_doublon(t):
    for i in range(len(t) - 1):
        if t[i] == t[i + 1]:
            return True
    return False</code></pre><br/>
Pour une liste triée d'un million d'éléments sans doublon, combien de<br/>
fois le test <code>t[i] == t[i + 1]</code> est-il évalué, et quel est le coût ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trier une table facilite la recherche de doublons : ils deviennent<br/>
voisins et un parcours linéaire suffit. Sans tri, il faudrait<br/>
comparer tous les couples, soit environ $n^2 / 2$ comparaisons.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $500\,000\,000\,000$ fois, coût quadratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait le nombre de tests d'une double boucle<br/>
comparant tous les couples d'éléments, nécessaire pour une liste<br/>
non triée. Ici il n'y a qu'une boucle, car dans une liste triée<br/>
les doublons sont voisins.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$1\,000\,000$ fois, coût linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle s'arrête à l'indice <code>len(t) - 2</code>, car le<br/>
dernier élément n'a pas de voisin à droite. On fait donc<br/>
$999\,999$ tests, pas $1\,000\,000$ ; le coût est bien linéaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $19$ fois, coût logarithmique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le fait que la liste soit triée n'entraîne pas une<br/>
dichotomie. Cette fonction examine les voisins un par un, sans<br/>
jamais éliminer de moitié, et fait $999\,999$ tests.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$999\,999$ fois, coût linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>i</code> prend les valeurs de $0$ à $999\,998$, soit<br/>
$999\,999$ tests, et aucun ne renvoie <code>True</code>. Comme la liste est<br/>
triée, deux valeurs égales sont forcément voisines : un seul<br/>
parcours suffit, d'où un coût linéaire.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes sur la<br/>
complexité, laquelle est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Maxime : « la notation O est un guide, pas une vérité absolue ».<br/>
Il faut toujours tester en pratique pour les cas réels, surtout sur<br/>
de petites entrées.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le tri par sélection a un coût quadratique dans le pire cas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : il fait environ n²/2 comparaisons, quel que soit l'ordre<br/>
initial.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un algorithme O(n) est toujours plus rapide qu'un algorithme O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : O(n) est plus rapide pour de grandes<br/>
entrées, mais sur de petites entrées un O(n²) avec une petite<br/>
constante peut battre un O(n) avec une grosse constante. Exemple :<br/>
avec n² opérations contre 100 × n, n² est plus petit tant que<br/>
n &lt; 100.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour les boucles imbriquées, on multiplie les complexités ; pour les séquences, on prend le maximum</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : règle de calcul standard.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La complexité O ignore les constantes multiplicatives</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : O(2n) = O(n) = O(100n).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q26 : Boucle while soustractive</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la complexité de la fonction<br/>
suivante en fonction de <code>n</code> ?<br/>
<pre><code>def f(n):
    while n &gt; 0:
        print(n)
        n = n - 3</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>À retenir : soustraire une constante à <code>n</code> à<br/>
chaque itération donne un coût linéaire ;<br/>
diviser <code>n</code> par une constante donne un coût<br/>
logarithmique. Cette distinction est la clé<br/>
pour reconnaître les algorithmes<br/>
logarithmiques.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(log n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la division par deux donne du<br/>
logarithmique. Ici on <strong>soustrait</strong> une<br/>
constante à chaque tour, donc le nombre<br/>
d'itérations est proportionnel à <code>n</code>, pas à<br/>
<code>log n</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le nombre d'itérations dépend<br/>
clairement de <code>n</code>. Pour <code>n = 30</code>, la boucle<br/>
tourne dix fois ; pour <code>n = 300</code>, elle<br/>
tourne cent fois. Ce n'est pas constant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(n)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>n</code> décroît par pas de 3.<br/>
Le nombre d'itérations vaut environ <code>n / 3</code>,<br/>
ce qui est O(n) car on absorbe la constante<br/>
multiplicative. Toute boucle <code>while</code> qui<br/>
soustrait une constante à <code>n</code> est en O(n).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il n'y a pas de double boucle. Le<br/>
coût est dominé par le nombre d'itérations<br/>
de l'unique <code>while</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q27 : Taille vs valeur de l'entrée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>On considère la fonction qui compte les<br/>
chiffres d'un entier positif :<br/>
<pre><code>def chiffres(n):
    c = 0
    while n &gt; 0:
        n = n // 10
        c += 1
    return c</code></pre><br/>
Quelle est sa complexité ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Subtilité importante : la « taille » d'un<br/>
entier <code>n</code> est son <strong>nombre de chiffres</strong>,<br/>
donc de l'ordre de <code>log(n)</code>. Les algorithmes<br/>
classiques sur les entiers sont dits<br/>
« linéaires » quand leur coût est<br/>
proportionnel au nombre de chiffres, c'est-à-<br/>
dire <code>O(log n)</code> en fonction de la valeur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n) en fonction de la valeur de n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : à chaque<br/>
itération, <code>n</code> est divisé par 10. Donc le<br/>
nombre d'itérations est de l'ordre de<br/>
<code>log₁₀(n)</code>, pas de <code>n</code>. Pour <code>n = 10⁶</code>, la<br/>
boucle ne tourne que sept fois, pas un<br/>
million.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(1) quelle que soit la valeur de n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle dépend de la valeur de<br/>
<code>n</code>. Plus <code>n</code> est grand, plus elle tourne<br/>
longtemps.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>O(log n) en fonction de la valeur de n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on divise <code>n</code> par 10 à<br/>
chaque itération, donc <code>log₁₀(n)</code> étapes.<br/>
C'est aussi exactement le <strong>nombre de chiffres</strong> de <code>n</code> dans son écriture<br/>
décimale. Une autre façon de le dire : la<br/>
complexité est <strong>linéaire</strong> par rapport à<br/>
la <strong>taille</strong> (nombre de chiffres) de <code>n</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>O(n²) en fonction de la valeur de n</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune double boucle ni structure<br/>
quadratique. Le coût ne grandit pas comme<br/>
<code>n²</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q28 : Coût des opérations sur les listes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi ces opérations sur une liste Python de<br/>
taille <code>n</code>, laquelle est la plus <strong>coûteuse</strong><br/>
au pire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Repères à connaître pour les listes Python : accès par indice,<br/>
<code>len</code> et <code>append</code> en O(1) ; <code>x in liste</code>, <code>max</code>, <code>min</code> et <code>sum</code> en<br/>
O(n), car ils parcourent toute la liste au pire. Ces ordres de<br/>
grandeur guident l'écriture d'un algorithme efficace.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>liste[0]</code> (lecture du premier élément)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'accès par indice est en O(1) sur une liste Python, qui<br/>
est un tableau. Pas besoin de parcourir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>x in liste</code> (test de présence)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : le test de présence est une<br/>
recherche linéaire cachée. Python compare<br/>
<code>x</code> à chaque élément jusqu'à le trouver ; si<br/>
la valeur est absente, il parcourt les <code>n</code><br/>
éléments, d'où un coût en O(n) au pire. Un<br/>
<code>in</code> répété sur une liste d'un million<br/>
d'éléments devient très lent.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>liste.append(x)</code> (ajout en fin)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>append</code> ajoute l'élément en fin de liste en temps<br/>
constant, sans parcourir les éléments déjà présents.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>len(liste)</code> (longueur de la liste)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>len</code> est en O(1). Python connaît la longueur de la liste<br/>
sans avoir à compter ses éléments.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q29 : Choisir selon la taille</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sur un PC moderne, on dispose d'<strong>une seconde</strong><br/>
pour exécuter un algorithme (environ 10⁸ opérations<br/>
Python). Quelle est la <strong>plus grande taille</strong><br/>
d'entrée que l'on peut traiter avec un<br/>
algorithme en O(n²) ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Repères de seuils pratiques (1 seconde de calcul, environ 10⁸<br/>
opérations) : O(2ⁿ) → n ≈ 25 ; O(n³) → n ≈ 500 ; O(n²) → n ≈ 10⁴ ;<br/>
O(n) → n ≈ 10⁸ ; O(log n) → n gigantesque. Indispensable pour<br/>
évaluer la faisabilité d'un algorithme avant de l'écrire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ 30 (trentaine)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait pour un algorithme exponentiel <code>O(2ⁿ)</code>. Avec<br/>
n = 30, on atteint déjà environ <code>10⁹</code> opérations, au-delà du<br/>
budget. Pour un algorithme quadratique, on peut traiter beaucoup<br/>
plus.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ 10⁸ (cent millions)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait pour un algorithme en<br/>
O(n) (linéaire). Pour un algorithme<br/>
quadratique, il faut prendre la racine<br/>
carrée du budget d'opérations.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Environ 10⁴ (dix mille)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : on cherche <code>n</code> tel que <code>n² ≤ 10⁸</code>, donc<br/>
<code>n ≤ √(10⁸) = 10⁴</code>. À retenir : un algorithme quadratique devient<br/>
lent dès quelques dizaines de milliers d'éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ 10⁶ (un million)</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour <code>n = 10⁶</code>, un algorithme<br/>
quadratique fait <code>10¹²</code> opérations, ce qui<br/>
prendrait environ trois heures. Hors<br/>
budget.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q30 : Une boucle intérieure qui grandit</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Combien de fois l'instruction <code>compteur = compteur + 1</code> est-elle<br/>
exécutée, en fonction de <code>n</code> ?<br/>
<pre><code>compteur = 0
for i in range(n):
    for j in range(i):
        compteur = compteur + 1</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Que la boucle intérieure fasse $n$ ou $i$ tours, le coût total reste<br/>
en $O(n^2)$ : le facteur $1/2$ ne change pas la classe.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$n(n-1)/2$ fois, soit un coût quadratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la boucle intérieure fait $0$, puis $1$, puis<br/>
$2$ tours, jusqu'à $n - 1$. La somme vaut $n(n-1)/2$, de<br/>
l'ordre de $n^2 / 2$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$n$ fois, soit un coût linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle intérieure multiplie le travail ; seule la<br/>
boucle extérieure fait $n$ tours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$n^2$ fois exactement, soit un coût quadratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $n^2$ serait le compte avec <code>range(n)</code> à l'intérieur ;<br/>
<code>range(i)</code> en fait environ la moitié. L'ordre de grandeur reste<br/>
quadratique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$2n$ fois, soit un coût linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : deux boucles imbriquées se multiplient, elles ne<br/>
s'additionnent pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q31 : Une boucle intérieure de taille fixe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la classe de complexité de ce programme en fonction de<br/>
<code>n</code> ?<br/>
<pre><code>for i in range(n):
    for j in range(10):
        total = total + t[i] * j</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour classer un programme, on ne garde que ce qui dépend de la<br/>
taille de l'entrée : les boucles de taille fixe comptent pour une<br/>
constante.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n)$, la boucle intérieure étant de taille fixe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $10n$ opérations, et une constante ne change<br/>
pas la classe. Le coût grandit comme $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n^2)$, deux boucles étant imbriquées l'une dans l'autre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'imbrication ne suffit pas ; il faut que les deux<br/>
boucles dépendent de $n$. Ici la seconde fait toujours dix tours.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(10n)$, une classe à part entre linéaire et quadratique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les constantes multiplicatives disparaissent dans la<br/>
notation $O$ ; $O(10n)$ se note $O(n)$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(1)$, le nombre dix étant fixé une fois pour toutes</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle extérieure dépend de $n$, le coût n'est pas<br/>
constant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q32 : Une recherche dans une boucle</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>La fonction <code>appartient(x, t)</code> fait une recherche linéaire dans la<br/>
liste <code>t</code>, de taille <code>n</code>. Quelle est la classe de complexité de ce<br/>
programme ?<br/>
<pre><code>for i in range(n):
    if appartient(t[i], u):
        nb = nb + 1</code></pre><br/>
La liste <code>u</code> est elle aussi de taille <code>n</code>.</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le coût d'un appel de fonction n'est pas constant : il faut le<br/>
multiplier par le nombre d'appels.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(n^2)$, chaque tour appelant une fonction de coût linéaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $n$ tours, et chacun parcourt jusqu'à $n$<br/>
éléments de <code>u</code>. Le coût total est de l'ordre de $n \times n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n)$, le programme ne contenant qu'une boucle</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la boucle cachée dans <code>appartient</code> compte aussi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(1)$, un appel de fonction étant une opération élémentaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un appel coûte ce que coûte la fonction appelée, ici un<br/>
parcours de <code>u</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(\log n)$, la fonction cherchant par dichotomie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la recherche est linéaire, et même dichotomique, la<br/>
boucle extérieure resterait en $n$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q33 : Accéder à une valeur par sa clé</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la classe de complexité de l'accès <code>d[cle]</code> dans un<br/>
dictionnaire Python de $n$ entrées ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choisir un dictionnaire plutôt qu'une liste transforme une<br/>
recherche linéaire en accès constant.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>$O(1)$, le temps ne dépendant pas de $n$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un dictionnaire calcule directement où ranger<br/>
chaque clé, ce qui rend l'accès constant en moyenne, quel que<br/>
soit $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n)$, toutes les clés devant être comparées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le coût d'une recherche dans une liste, pas dans<br/>
un dictionnaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(\log n)$, les clés étant triées en interne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les clés d'un dictionnaire ne sont pas triées, et<br/>
l'accès est encore plus rapide qu'une dichotomie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>$O(n^2)$, chaque clé étant comparée à toutes les autres</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune double boucle n'intervient dans un accès par<br/>
clé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q34 : Estimer le temps d'un algorithme quadratique</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un algorithme en $O(n^2)$ traite $1\,000$ éléments en $1$ s.<br/>
Combien de temps lui faut-il pour $10\,000$ éléments ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Connaître la classe d'un algorithme permet d'extrapoler : en<br/>
$O(n^2)$, multiplier la taille par $k$ multiplie le temps par<br/>
$k^2$.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Environ $100$ s</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la taille est multipliée par dix, donc le temps<br/>
par dix au carré, soit $100$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $10$ s</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un temps multiplié par dix correspondrait à un<br/>
algorithme linéaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toujours $1$ s</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un coût quadratique dépend fortement de la taille.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $100 \times 100$ s</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le facteur est le carré du rapport des tailles, pas<br/>
son carré au carré.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q35 : Deux tris sur un million d'éléments</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pour $n = 10^6$, on compare un tri en $O(n \log_2 n)$ et un tri en<br/>
$O(n^2)$, avec la même constante. Quel est l'ordre de grandeur du<br/>
rapport de leurs coûts ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Sur un million d'éléments, un tri quadratique est des dizaines de<br/>
milliers de fois plus lent qu'un tri en $n \log n$ : la classe de<br/>
complexité décide de ce qui est faisable.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Environ $50\,000$, soit $n / \log_2 n$</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : $n^2 = 10^{12}$ et $n \log_2 n \approx 2 \times<br/>
10^7$. Le rapport vaut $10^{12} / (2 \times 10^7) = 5 \times<br/>
10^4$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $2$, les deux étant presque linéaires</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $n^2$ n'a rien de linéaire ; l'écart est énorme pour<br/>
$n$ grand.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $10^6$, soit $n$, le rapport des tailles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le rapport est $n / \log_2 n$, pas $n$, car le tri en<br/>
$n \log_2 n$ ne coûte pas $n$.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Environ $20$, soit $\log_2 n$, le facteur du tri efficace</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : $20$ est le rapport entre $n \log_2 n$ et $n$, pas<br/>
entre $n^2$ et $n \log_2 n$.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q36 : Compter plutôt que chronométrer</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi évalue-t-on le coût d'un algorithme en comptant des<br/>
opérations plutôt qu'en mesurant un temps d'exécution ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La complexité est une propriété de l'algorithme, pas de<br/>
l'ordinateur qui l'exécute.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Parce que le compte ne dépend ni de la machine ni du langage</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : un chronomètre mesure un programme sur une<br/>
machine donnée ; le nombre d'opérations décrit l'algorithme<br/>
lui-même et permet de comparer des méthodes.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les temps d'exécution sont impossibles à mesurer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : on mesure très bien un temps, mais il ne caractérise<br/>
pas l'algorithme.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que les opérations sont toutes de même durée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : elles ne durent pas exactement le même temps ; on les<br/>
suppose bornées, ce qui suffit pour un ordre de grandeur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Parce que le nombre d'opérations est toujours plus petit que le temps</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux grandeurs ne se comparent pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Complexité algorithmique — Q37 : Ce qu'est une opération élémentaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans le décompte du coût d'un algorithme, que considère-t-on comme<br/>
une opération élémentaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Compter les opérations élémentaires demande de voir ce que cache<br/>
chaque instruction : une boucle, un appel ou un test d'appartenance<br/>
peuvent valoir $n$ opérations.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une affectation, une comparaison ou un calcul, de durée bornée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ces opérations prennent un temps qui ne dépend<br/>
pas de la taille des données. Les compter donne l'ordre de<br/>
grandeur du coût.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un tour de boucle complet, quel que soit son contenu</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un tour de boucle peut contenir d'autres boucles ou<br/>
des appels coûteux.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un appel de fonction, quel que soit le coût de la fonction appelée</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un appel coûte ce que coûte la fonction, qui peut<br/>
parcourir toute une liste.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une ligne de code Python, quelle que soit l'instruction qu'elle contient</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une seule ligne peut cacher un parcours entier, comme<br/>
<code>x in liste</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
