forked from menault/2026_TD3_DEV51_Qualite_Algo
F7 : compter les paires opposées par dichotomie (O(n²) → O(n log n))
La double boucle testait les n(n-1)/2 = 450 millions de paires. Sur le tableau trié par F1, deux recherches dichotomiques donnent en O(log n) le nombre de transactions de montant -v. On somme ces effectifs, on retire les montants nuls (comptés avec eux-mêmes) et on divise par 2 (chaque paire est vue deux fois). F7 est donc appelée après le tri dans main. Temps (-O2) : 0,92 s → 0,25 s. Empreinte inchangée (ff68d260a7a58441). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -163,15 +163,37 @@ const Transaction *rechercher_par_id(const Transaction *t, const int *position,
|
||||
return &t[position[id]];
|
||||
}
|
||||
|
||||
/* F7 : nombre de paires de transactions de montants opposés (a + b = 0) */
|
||||
/* Premier indice i tel que t[i].montant >= v, dans t trié par montant
|
||||
* croissant (recherche dichotomique, O(log n)). */
|
||||
int premier_indice(const Transaction *t, int n, long v)
|
||||
{
|
||||
int debut = 0, fin = n;
|
||||
while (debut < fin) {
|
||||
int milieu = (debut + fin) / 2;
|
||||
if (t[milieu].montant < v)
|
||||
debut = milieu + 1;
|
||||
else
|
||||
fin = milieu;
|
||||
}
|
||||
return debut;
|
||||
}
|
||||
|
||||
/* Nombre de transactions de montant v, dans t trié par montant croissant */
|
||||
int effectif(const Transaction *t, int n, long v)
|
||||
{
|
||||
return premier_indice(t, n, v + 1) - premier_indice(t, n, v);
|
||||
}
|
||||
|
||||
/* F7 : nombre de paires de transactions de montants opposés (a + b = 0).
|
||||
* t doit être trié par montant (F1). On compte, pour chaque transaction, les
|
||||
* transactions de montant opposé : chaque paire est vue deux fois, et chaque
|
||||
* montant nul se compte lui-même une fois en trop. */
|
||||
long nb_paires_opposees(const Transaction *t, int n)
|
||||
{
|
||||
long nb = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = i + 1; j < n; j++)
|
||||
if (t[i].montant + t[j].montant == 0)
|
||||
nb++;
|
||||
return nb;
|
||||
nb += effectif(t, n, -t[i].montant);
|
||||
return (nb - effectif(t, n, 0)) / 2;
|
||||
}
|
||||
|
||||
/* F8 : nombre de façons de rendre une somme avec les pièces disponibles */
|
||||
@@ -279,13 +301,12 @@ int main(void)
|
||||
int debut, fin;
|
||||
long meilleure = meilleure_periode(totaux_jours, NB_JOURS, &debut, &fin);
|
||||
|
||||
long nb_paires = nb_paires_opposees(t, NB_TRANSACTIONS);
|
||||
|
||||
int categories[12] = {0};
|
||||
for (int i = 0; i < NB_TRANSACTIONS; i++)
|
||||
categories[categorie(&t[i])]++;
|
||||
|
||||
trier_par_montant(t, NB_TRANSACTIONS);
|
||||
long nb_paires = nb_paires_opposees(t, NB_TRANSACTIONS); /* a besoin du tri */
|
||||
|
||||
long nb_facons = nb_facons_rendre(MONTANT_MONNAIE, NB_PIECES);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user