Informatică, întrebare adresată de feherdarius, 9 ani în urmă

Am gresit ceva la acest algoritm , daca da , ce?
Cerința
Se dau n numere naturale nenule. Ordonați descrescător cele n numere după numărul lor de divizori.
Date de intrare
Fișierul de intrare sortare_divizori.in conține pe prima linie numărul n, iar pe a doua linie n numere naturale nenule separate prin câte un spațiu.
Date de ieșire
Fișierul de ieșire sortare_divizori.out va conține cele n numere aflate pe a doua linie a fișierului de intrare ordonate descrescător după numărul de divizori.
Restricții și precizări
1 ≤ n ≤ 1000
numerele de pe a doua linie a fișierului de intrare vor fi mai mici decât 1.000.000.000
dacă există mai multe numere care au același număr de divizori, acestea vor fi ordonate crescător

Codul:

Anexe:

AntiEaglesDavids: #include <fstream>
using namespace std;
ifstream fin("sortare_divizori.in");
ofstream fout("sortare_divizori.out");

int main()
{
int n;
fin >> n;
int v[n], a[n];

for(int i = 1, k = 0; i <= n; i++, k = 0) {
fin >> v[i];

for(int d = 1; d <= v[i]; d++)
if(v[i] % d == 0)
k++;

a[++a[0]] = k;
}

for(int i = 1; i < n; i++)
for(int j = i + 1; j <= n; j++)
if(a[i] <= a[j]) {
swap(v[i], v[j]);
swap(a[i], a[j]);
}

for(int i = 1; i <= n; i++)
fout << v[i] << " ";
return 0;
}
AntiEaglesDavids: am mai curatat din variabile si am facut sortarea un pic mai scurta
blindseeker90: "dacă există mai multe numere care au același număr de divizori, acestea vor fi ordonate crescător" algoritmul tau nu verifica faptul ca numerele cu acelasi numar de divizori sunt ordonate crescator.. De aceea feher darius pune conditia: a[i]==a[j] && v[i]>v[j]) atunci cand face inversiunea de termeni.
AntiEaglesDavids: ups... asta imi trebuie daca nu citesc pana la capat :))

Răspunsuri la întrebare

Răspuns de blindseeker90
4
Salut,
Partea din cod care pune probleme este cea in care faci sortarea in mod descrescator. Faci inversiunea dintre 2 elemente pentru valorile numerelor, dar nu faci inversiunea si pentru numarul de divizori.

Un exemplu simplu
Sa zicem ca ai datele de intrare
6
12 32 19 43 14 21
Aceste numere au numarul de divizori
6 6 2 2 4 4
Pana la pozitia a treia nu se intampla nimic, pentru ca deja sunt descrescator
la a treia pozitie, compara 2 cu 2, sunt acelasi, dar 19<43, deci nu se face inversiunea
compara apoi 2 cu 4, 2<4 atunci se face inversiunea DOAR de numere, deci sirul devine 12 32 14 43 19 21 dar sirul cu numarul de divizori ramane 6 6 2 2 4 4. Apoi face comparatia cu urmatorul numar: 2 fata de 4. 2 este mai mic fata de 4, atunci se face inversiunea, si avem
12 32 21 43 19 14
Din acest moment, 14 va aparea dupa 21, si algoritmul da gres.
Deci tot ce trebuie sa faci este sa faci schimbarea de elemente si in vectorul a

   for(i=1; i<b; i++)
        for(j=i+1; j<=b; j++)
            if((a[i]<a[j] ) || (a[i]==a[j] && v[i]>v[j]))
            {
                aux=v[i];
                v[i]=v[j];
                v[j]=aux;

                aux=a[i];
                a[i]=a[j];
                a[j]=aux;
            }

AntiEaglesDavids: de ce ai 2 swap-uri :O?
AntiEaglesDavids: ah nvm nu am observat ca sunt pe array-uri diferite my bad
feherdarius: Da,bine zici.. Nu am fost suficient de atent. Multumesc blindeeker!
Alte întrebări interesante