Cum funcționează
Asta e prima problemă dintr-o familie întreagă: sortare nu după valoare, ci după o valoare
calculată din ea. Ideea care le rezolvă pe toate e aceeași.
Un algoritm de sortare compară elemente două câte două. Dacă vrei alt criteriu decât valoarea
însăși, ai două variante:
- calculezi criteriul la fiecare comparație — corect, dar risipitor;
- calculezi criteriul o dată, la citire, și îl ții într-un vector paralel — mult mai rapid.
Varianta a doua nu e doar o optimizare. La n = 10000, o sortare simplă face aproximativ 50 de
milioane de comparații. Dacă fiecare recalculează două sume de cifre, ajungi la sute de milioane de
operații inutile și programul chiar se simte. Cu cheile precalculate, comparația e o singură
scădere.
Partea critică: cheia se mută împreună cu valoarea. Când interschimbi v[i] cu v[j], trebuie
să interschimbi și sc[i] cu sc[j]. Dacă uiți, vectorul de chei rămâne în ordinea veche, iar
sortarea continuă să compare numere cu sumele altor numere — rezultatul iese aproape ordonat, deci
greșeala nu sare în ochi.
Tiparul de vectori paraleli (valoare + cheie, mutate împreună) e util de reținut: apare la sortări
după nume, după medie, după orice criteriu derivat.
Suma cifrelor folosește bucla standard x % 10 / x /= 10, aceeași din toate problemele cu cifre.
Enunțul spune explicit că ordinea între numerele cu aceeași sumă nu contează, ceea ce îți dă voie
să folosești orice algoritm de sortare. Când enunțul cere un criteriu secundar, lucrurile se
schimbă — vezi sortarea după cifra de control.
Greșeli frecvente
- Interschimbarea doar a valorilor, nu și a cheilor — cea mai frecventă greșeală a problemei, și
cea mai greu de observat, pentru că rezultatul pare aproape corect.
- Recalcularea sumei în interiorul comparației — funcționează, dar la limita din enunț devine
lent fără motiv.
sum inițializat în afara funcției sau nereinițializat între apeluri — sumele se adună una
peste alta.
- Sortarea după valoare și afișarea sumei — se citește enunțul de două ori: se cer numerele,
ordonate după sumă.