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

Salut,am facut problema asta si nu stiu ce nu da bine,enuntul:
Se considera un numar natural n. Daca numarul format din primele doua cifre este perfect atunci se va afisa numarul total de cifre ale lui n, in caz contrar se va afisa numarul de cifre pare pe care le contine.

#include
int main()
{
int cu,cz,n,i,nou=0,s=0,nr=0,d,cp=0,x,cif;
scanf("%d",&n);
x=n;
if(n!=0&&nou==0)
{
cu=n%10;
n=n/10;
cz=n%10;
n=n/10;
nou=nou*10+cu;
nou=nou*10+cz;
}
for(d=1; d*d<=nou; d++)
if(nou%d==0)
s=s+d;
if(x==s)
{
do
{
x=x/10;
nr++;
printf("%d ",nr);
break;
}
while(x!=0);
}
else
if(x!=s)
do
{
cif=x%10;
if(cif%2==0)
cp++;
x=x/10;
}while(x!=0);
printf("%d ",cp);
return 0;
}


AntiEaglesDavids: puteai sa folosesti ca o rezolvare alternativa un string si terminai totu' in 5-6 randuri maxim...

Răspunsuri la întrebare

Răspuns de antonii
0
Aaaa....banuiesc ca nu esti expert in arta programatului (no offense).
Desi e lung am detectat doar doua greseli:
    1) Problema nu-ti spune ca n are doar 2 cifre. Poate sa aiba si 200 de cifre. Cand folosesti smecheria cu modul de 10 tu iei ultimele 2 cifre 
       Aici: "cu=n%10;
                n=n/10;
                cz=n%10;
                n=n/10;"
 Daca n=12345 atunci n%10 =5. Deci iei ultimele cifre. La aceasta problema poti folosii doua functii:
     int len_of_nr(int nr){
           // Ia numarul de cifre din nr.
           int count=0;
           do{
                      count++;
                      nr/=10;
           }while(nr!=0);
           return count;
     }
si
     #include <cmath>
     int get_char(int nr,int char_count,int pos){
           // Ia cifra la o anumita pozitie din nr
           // (1 e la coada pana la inceput-> pos:n..321)
                
           int div=1;
           for(div=1;div<pow(10,pos-1);div*=10);
           return (nr/div)%10;
     }

2) Nu inteleg de ce ai facut asta aici:
"do
{
x=x/10;
nr++;
printf("%d ",nr);
break;
}
while(x!=0);" _Tradus :scoate din x ultima cifra; aduna 1 la nr; afiseaza nr; opreste loop-ul; si atat. Adica daca initial nr era 0 acum va afisa 1 si se va operii..de ce? tinand cont de faptul ca mai jos ai facut cum trebuie:
"
do
{
cif=x%10;
if(cif%2==0)
cp++;
x=x/10;
}while(x!=0);
printf("%d ",cp);
return 0;
}" ->aici e perfect...

*3) -o mica optimizare/neintelegere?
Aici:
"
if(nou%d==0)
s=s+d;
if(x==s)
{" -De ce ai facut asa? Da..aici verificai cum trebuie daca "nou" e patrat perfect insa ce e cu s+=d ? Adica daca toti divizorii (speciali) a lui "nou" adunati fac cat x atunci...? Asta e cam gresit.
Puteai face asa:

for(d=1; d*d<=nou; d++)
    if(nou%d==0){
        isPerfect=true;
        break;
    }

if(isPerfect)
   do....

else
.....

antonii: ooooo....scuze atunci pentru numarul 3...
alecsapostol96: La 2) am facut asa pentru ca imi cerea sa afisez numarul de cifre,si in caz contrat numarul de cifre pare.
alecsapostol96: De aceea am pus acel "else" acolo :)
AntiEaglesDavids: for(div=1;div<pow(10,pos-1);div*=10); pow-ul ala strica totul :(
antonii: am facut asa ca sa fie mai rapid (?-n-am testat). Insa puteam sa-l optimizez si sa-l pun intr-o variabila inainte de for. Insa n-a spus ca viteza conteaza.
antonii: Alecapostol: la 2->ai oprit loop-ul (while-ul) inainte de a putea numara ceva. In codul tau indiferent de cate cifre are x iti va afisa tot timpul 1.
AntiEaglesDavids: nu numai ca viteza e varza cu pow() dar iti va si strica conditia in unele cazuri. pow() poate returna de ex. in loc de 1000 numarul 999.99999876 (ceva de genu). Cum ai zis si tu, mai bine pastrezi puterile lui zece intr-o variabila si o inmultesti la fiecare pas. Asa e mult mai rapid si mult, mult mai safe.
AntiEaglesDavids: si nu depinzi de <cmath> :p
alecsapostol96: Atunci sa sterg acel break?
antonii: da...dar si printf din while. De abia dupa ce se termina acel loop poti pune printf
Alte întrebări interesante