On considère un tableau bidimensionnel d'entiers positifs, dont chaque ligne et chaque colonne est triée dans l'ordre croissant. On souhaite savoir si un élément cible est présent dans ce tableau.
Dans cette grille, chaque ligne et chaque colonne est triée.
Les lignes et les colonnes sont numérotées à partir du rang \(0\).
\(42\) est présent à la ligne \(0\), colonne \(2\).
\(24\) est absent.
Accès aux valeurs
Le tableau bidimensionnel grille utilisé ici n'est pas une liste Python et vous n'avez pas un accès direct aux données qu'il contient.
En revanche, vous avez à votre disposition trois fonctions nb_lignes, nb_colonnes, valeur (déjà chargées en mémoire) telles que :
nb_lignes(grille) renvoie le nombre \(m\) de lignes de grille ;
nb_colonnes(grille) renvoie le nombre \(n\) de colonnes de grille ;
valeur(grille,i,j) renvoie la valeur de grille située à l'intersection de la ligne i et de la colonne j.
Écrire une fonction recherche qui prend en paramètres un élément cible et une grille grille. Cette grille possède la propriété que chaque ligne et chaque colonne est triée.
Si l'élément cible est absent de grille alors la fonction renvoie None.
Sinon la fonction renvoie le tuple (i,j) tel que valeur(grille,i,j) soit égale à cible.
Attention
Si on teste toutes les valeurs d'une grille avec \(m\) lignes et \(n\) colonnes, on devra lire dans le pire des cas \(m \times n\) valeurs.
On demande d'écrire un programme plus efficace lisant dans le pire des cas \(m + n - 1\) valeurs.
Le non respect de cette consigne provoquera une erreur.
Dans les tests, la fonction nb_acces, déjà chargée en mémoire, permet de connaître le nombre de lectures de la grille.
Exemples
Avec la grille définie comme dans le premier test, on a :
On peut commencer par lire la valeur se trouvant au coin supérieur droit de la grille.
Pour la grille de l'exemple, on pourrait écrire un algorithme qui :
pour la recherche de \(88\) ne lise que successivement \(63\) - \(80\) - \(95\) - \(88\) ;
pour la recherche de \(52\) ne lise que successivement \(63\) - \(42\) - \(67\) - \(52\) ;
pour la recherche de \(30\) ne lise que successivement \(63\) - \(42\) - \(33\) - \(11\) - \(20\) - \(25\)
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)