Съвършено число

Напишете програма, която въвежда естествено число N и проверява дали то е съвършено (равно на сумата от делителите си, без самото число)

Публикувано в 11а, 11в с етикети , . Постоянна връзка.

8 коментара по Съвършено число

  1. krisizdravi95 каза:
    { int N,suma=0;
    cout<<"Vuvedete estestveno chislo: ";
    cin>>N;
    if((N<=0)||(!cin.good()))
    cout<<"Tova ne e estestveno chislo.\n";
    else
    {
    for(int i=1; i<N; i++){
    if(N%i==0)
    suma+=i;
    }
    if(N==suma)
    cout<<"Chisloto e suvursheno.\n";
    else cout<<"Chisloto ne e suvursheno.\n";
    }
    
    return 0;
    }
    
    • Данаил каза:

      Я, krisizdravi95 с решение? И използване на функции извън материала? Мноооого добре! :-)
      Задачата е вярна и много добре структурирана. Само бих препоръчал вложените команди да се пишат по-навътре, за да е по-прегледен кода…

  2. Gadget каза:
    int N,suma;
        suma=0;
        cout<<"Vavedete estestveno chislo N: ";
        cin>>N;
        for(int i=1;i<=N;i++){
         if((N%i==0)&&(i!=N))
         //Namirame delitelite i gi pribavqme kum sumata
          suma+=i;
        }
        if(N==suma)
         cout<<"Vuvedenoto chislo e suvursheno!"<<endl;
        else
         cout<<"Vuvedenoto chislo ne e suvursheno!"<<endl;
    
  3. dreanor каза:
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    /* Pri wsqko powikwane na funkciqta delitela se uwelichawa s 1 dokato ne dostigne chisloto.
       Usloweito da e strogo po-golqmo e neobhodimo za da se izbegne delenie na samoto chislo. */
    int suwursheno(int chislo,int delitel,int suma){
        
        if (delitel<chislo)
           {
             if ((chislo%delitel)==0) suma+=delitel;
             suwursheno(chislo,delitel+1,suma);
           }
        else if (suma==chislo) cout<<chislo<<" e suwursheno \n";
             else cout <<chislo<<" ne e suwursheno \n";
        
        }
    int main(int argc, char *argv[])
    {
        int chislo,suma=1,delitel=2; //Wsqko chislo se deli na 1, zatowa go izkliuchwam ot prowerkata i go dobawqm w sumata.
        cout<<"Wuwedete kandidata za suwursheno chislo ";
        cin>>chislo;
        if ((chislo<=0)||(!cin.good())) cout<<"Ne e estestweno chislo\n";
        else suwursheno(chislo,delitel,suma);    
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    
    • Данаил каза:

      Калояне, много добре! Явно започваш да се специализираш в рекурсиите :-)

      Задачата е вярна, имам само една забележка по функцията – тъй като в твоя случай тя не връща резултат, би трябвало да я укажеш от тип void вместо int. Но, макар че не е грешно и така, не печелиш много от функции, които печатат на екрана (освен ако задачата им не е изрично това) – защото така функцията престава да бъде инструмент, нещо универсално, което може да бъде използвано по най-различни начини.

      Ето ти два примера за различна употреба на създадената от теб функция (с леки промени по кода):

      #include <cstdlib>
      #include <iostream>
       
      using namespace std;
      /* Pri wsqko powikwane na funkciqta delitela se uwelichawa s 1 dokato ne dostigne chisloto.
         Usloweito da e strogo po-golqmo e neobhodimo za da se izbegne delenie na samoto chislo. */
      bool suwursheno(int chislo,int delitel,int suma){
           
          if (delitel<chislo)
             {
               if ((chislo%delitel)==0) suma+=delitel;
                return suwursheno(chislo,delitel+1,suma);
             }
          else return (suma==chislo);
           
          }
      int main(int argc, char *argv[])
      {
          int chislo,suma=1,delitel=2; //Wsqko chislo se deli na 1, zatowa go izkliuchwam ot prowerkata i go dobawqm w sumata.
          cout<<"Wuwedete kandidata za suwursheno chislo ";
          cin>>chislo;
          if ((chislo<=0)||(!cin.good())) cout<<"Ne e estestweno chislo\n";
          // използваме функцията за да решим задачата
          else if (suwursheno(chislo,delitel,suma))
      		cout<<chislo<<" e suwursheno \n";
          else cout <<chislo<<" ne e suwursheno \n";   
      	// използваме същата функция за друга цел
          cout<<"A eto i niakolko savarsheni chisla:\n";
          for (chislo=1; chislo<10000; chislo++) {
      		suma=1; delitel=2;
      		if (suwursheno(chislo,delitel,suma))
      		  cout<<chislo<<endl;
      	}
          system("PAUSE");
          return EXIT_SUCCESS;
      }

      Ако увеличиш горната граница на търсенето на съвършени числа на 1 милион да кажем, ще забележиш едно чувствително забавяне на завършването на програмата. Ето кога ефективността на кода става от решаваща важност – при множество изчисления забавянето от всеки оператор е от значение, защото се умножава по 100000. Става важно и това кой точно подход да бъде избран – например в случая на рекурсия ще имаме до 100000 вложени едно в друго извиквания на една функция, което може да дойде малко множко. Пробвай тази задача с цикъл и с рекурсия и пиши кой подход е по-бърз и кой харчи повече памет.

  4. dreanor каза:
    #include <cstdlib>
    #include <iostream>
    #include <time.h>
    
    clock_t startm, stopm;
     
    #define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
    #define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
    #define PRINTTIME printf( "time: %6.25f", ((double)stopm-startm)/CLOCKS_PER_SEC);
    
    using namespace std;
    /* Pri wsqko powikwane na funkciqta delitela se uwelichawa s 1 dokato ne dostigne chisloto.
       Usloweito da e strogo po-golqmo e neobhodimo za da se izbegne delenie na samoto chislo. */
    void suwursheno(int chislo,int delitel,int suma){
        
        if (delitel<chislo)
           {
             if ((chislo%delitel)==0) suma+=delitel;
             suwursheno(chislo,delitel+1,suma);
           }
        else if (suma==chislo) cout<<chislo<<" e suwursheno \n";
             else cout <<chislo<<" ne e suwursheno \n";
        
        }
    int main(int argc, char *argv[])
    {
        int chislo,suma=1,delitel=2; //Wsqko chislo se deli na 1, zatowa go izkliuchwam ot prowerkata i go dobawqm w sumata.
        cout<<"Wuwedete kandidata za suwursheno chislo ";
        cin>>chislo;
        START;
        if ((chislo<=0)||(!cin.good())) cout<<"Ne e estestweno chislo\n";
        //else suwursheno(chislo,delitel,suma);
        else for(delitel;delitel<chislo;delitel++)
             if ((chislo%delitel)==0) suma+=delitel;
        if (suma==chislo) cout<<chislo<<" e suwursheno \n";
             else cout <<chislo<<" ne e suwursheno \n";
        STOP;
        PRINTTIME; cout<<endl;   
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    Измерих времето и с цикъл for се оказа по-удачно от използването на функция с рекурсия. Също позволява работа с големи числа.

    • Данаил каза:

      Охо, използваш и макроси :-) Браво, хубаво е, че ползваш и странична литература – това е начинът човек непрекъснато да се ъпгрейдва. А в днешно време с помощта на Гугъл и Интернет това не е чак толкова трудна и времеемка задача – просто трябва човек да има желание…

      Да, конкретно за тази задача е по-удачно с цикъл. Можеше да провериш в Task manager-a и колко памет заема програмата при работа – при рекурсията ще е със сигурност доста повече. Но има други задачи, в които рекурсивното решение е много по-бързо и кодът е по-кратък и прост. Така че се преценява според случая. Ако се очаква да има много голям брой рекурсивни извиквания, тогава е по-добре да се избягват рекурсиите. Виж за повече пояснения например тук, секцията „Условия за избор на рекурсивно решение“.

      Ще очаквам с интерес и следващите решения…

Вашият коментар