💻 Examen du Baccalauréat Pratique – Session 2026 (Sujet 2)

Épreuve Pratique : Algorithmique et Programmation (Section : Sciences de l’informatique)

📥 Télécharger les Sujets PDF (Sujet 2) 📦 Télécharger ressources (Algo2.rar)

📖 Texte de l’Épreuve & Contexte (Sujet 2)

RÉPUBLIQUE TUNISIENNE — MINISTÈRE DE L’ÉDUCATION
EXAMEN DU BACCALAURÉAT — SESSION 2026
Épreuve Pratique : Algorithmique et Programmation | Section : Sciences de l’informatique | Durée : 1h 30min

Contexte Général :

Dans un lycée, des observations ont montré que certaines zones de la cour pendant la récréation présentent une forte concentration d’élèves pouvant provoquer des tensions[cite: 14]. Pour améliorer la surveillance, un relevé du nombre d’élèves présents est modélisé sous forme d’une grille rectangulaire (matrice d’entiers)[cite: 14].

Définition des Points Croissants :

Un point croissant d’une matrice $M$ de $L$ lignes et $C$ colonnes est tout élément $M[i,j]$ vérifiant la relation :
M[i,j] = M[i,j-1] + M[i-1,j] + M[i+1,j]
Avec : $1 \le i \le L-2$ (exclusion des lignes 0 et $L-1$) et $1 \le j \le C-1$ (exclusion de la colonne 0)[cite: 14].

Objectifs de l’application :

  • Saisir les dimensions $L$ et $C$ ($2 \le L, C \le 100$) et remplir la matrice $M$[cite: 15].
  • Rechercher et afficher les points croissants contenus dans la matrice ainsi que leur nombre[cite: 15].
  • Rechercher et afficher les zones sous-occupées (valeur inférieure ou égale à un seuil $S \le 5$)[cite: 15].

🖥️ Simulation Interactive (Recherche de Points Croissants)

Testez l’algorithme de détection des points croissants sur la matrice de référence de l’énoncé :

Matrice M (Exemple type)

Ligne 0 : 12, 5, 3, 52, 7
Ligne 1 : 4, 13, 3, 2, 18
Ligne 2 : 6, 4, 16, 9, 2
Ligne 3 : 1, 11, 10, 6, 2

Résultat : Cliquez sur le bouton pour lancer la recherche.

Objets Qt (Interface)

L, C : QLineEdit
TextEdit : QTextEdit (Contenu)
Seuil : QLineEdit

🛠️ Solutions en Python (RempliM.py & Recherche.py)

1. RempliM.py (Saisie et validation)

from PyQt5.uic import loadUi
from PyQt5.QtWidgets import *

def Valide(L, C):
    return (2 <= L <= 100) and (2 <= C <= 100)

def Remplissage():
    try:
        L = int(w.L.text())
        C = int(w.C.text())
    except ValueError:
        QMessageBox.critical(w, "Erreur", "Veuillez saisir des entiers valides pour L et C")
        return

    if not Valide(L, C):
        QMessageBox.critical(w, "Erreur", "Les dimensions ne sont pas conformes aux contraintes")
        return

    texte = w.textEdit.toPlainText().strip().split('\n')
    if len(texte) != L:
        QMessageBox.critical(w, "Erreur", "Le contenu saisi n'est pas conforme aux contraintes")
        return

    matrice = []
    for ligne in texte:
        elements = ligne.strip().split()
        if len(elements) != C:
            QMessageBox.critical(w, "Erreur", "Le contenu saisi n'est pas conforme aux contraintes")
            return
        try:
            ligne_entiers = [int(x) for x in elements]
        except ValueError:
            QMessageBox.critical(w, "Erreur", "Tous les éléments doivent être des entiers naturels")
            return
        matrice.append(ligne_entiers)

    f = open("cour.txt", "w")
    f.write(str(L) + " " + str(C) + "\n")
    for ligne in texte:
        f.write(ligne.strip() + "\n")
    f.close()
    QMessageBox.information(w, "Succès", "Matrice enregistrée avec succès dans cour.txt")

app = QApplication([])
w = loadUi("InterfRempl.ui")
w.show()
w.btEnregistrer.clicked.connect(Remplissage)
app.exec_()

2. Recherche.py (Points croissants et zones sous-occupées)

from PyQt5.uic import loadUi
from PyQt5.QtWidgets import *

def RechAffPC():
    try:
        f = open("cour.txt", "r")
    except FileNotFoundError:
        QMessageBox.critical(w, "Erreur", "Fichier cour.txt introuvable. Veuillez remplir la matrice.")
        return

    enquete = f.readline().split()
    L = int(enquete[0])
    C = int(enquete[1])
    
    M = []
    for _ in range(L):
        M.append([int(x) for x in f.readline().split()])
    f.close()

    points_croissants = []
    for i in range(1, L - 1):
        for j in range(1, C):
            if M[i][j] == M[i][j-1] + M[i-1][j] + M[i+1][j]:
                points_croissants.append((M[i][j], i, j))

    f_res = open("PointsCroissant.txt", "w")
    w.textEdit.clear()
    for val, i, j in points_croissants:
        w.textEdit.append(f"{val} {i} {j}")
        f_res.write(f"{val} {i} {j}\n")
    f_res.close()
    
    w.textEdit.append(f"Le nombre de points croissants est : {len(points_croissants)}")

def RechAffZones():
    try:
        s = int(w.seuilInput.text())
    except ValueError:
        QMessageBox.critical(w, "Erreur", "Valeur du seuil incorrecte !")
        return

    if not (0 <= s <= 5):
        QMessageBox.critical(w, "Erreur", "Valeur du seuil incorrecte !")
        return

    try:
        f = open("cour.txt", "r")
    except FileNotFoundError:
        QMessageBox.critical(w, "Erreur", "Fichier cour.txt introuvable.")
        return

    enquete = f.readline().split()
    L = int(enquete[0])
    C = int(enquete[1])
    
    M = []
    for _ in range(L):
        M.append([int(x) for x in f.readline().split()])
    f.close()

    zones = []
    for i in range(L):
        for j in range(C):
            if M[i][j] <= s:
                zones.append((M[i][j], i, j))

    w.textEdit.clear()
    for val, i, j in zones:
        w.textEdit.append(f"{val} {i} {j}")
    w.textEdit.append(f"Le nombre de zones sous occupées est : {len(zones)}")

def Effacer():
    w.textEdit.clear()

app = QApplication([])
w = loadUi("InterfRech.ui")
w.show()
w.btPC.clicked.connect(RechAffPC)
w.btZones.clicked.connect(RechAffZones)
w.btEffacer.clicked.connect(Effacer)
app.exec_()