Zadanie liczby doskonale

0

Wykonałem poniższe zadanie, lecz sprawdzarka nie przepuszcza, dostaje 2/3 pkt i nie pisze przy czym się wywala, wie ktoś może co jest źle?
Tresc zadania:

Wejście
Liczba naturalna N (N<1000), a następnie N liczb naturalnych (nie większych niż 32000).

Wyjście
Dla każdej z podanych na wejściu liczb program powinien wydrukowań na ekranie wiersz postaci:

X - liczba doskonala/nadmiarowa/deficytowa
w zależności od typu liczby.

Przykładowe wejście
6 15 28 6 56 22 496

Przykładowe wyjście
15 - liczba nadmiarowa
28 - liczba doskonala
6 - liczba doskonala
56 - liczba deficytowa
22 - liczba nadmiarowa
496 - liczba doskonala

#include <iostream>
using namespace std;

int main()
{
  int n;
  cin >> n;
  if (n < 1000)
  {

    int *tab = new int[n];
    for (int i = 0; i < n; i++)
    {
      int x = 0;
      cin >> tab[i];
    }

    for (int k = 0; k < n; k++)
    {
      int sum = 0;

      for (int d = 1; d < tab[k]; d++)
      {
        if (tab[k] % d == 0)
        {
          sum += d;
        }
      }

      if (tab[k] != 0 && tab[k] < 32000)
      {
        if (tab[k] < sum)
        {
          cout << tab[k] << " - liczba deficytowa" << endl;
        }
        else if (tab[k] > sum)
        {
          cout << tab[k] << " - liczba nadmiarowa" << endl;
        }
        else
        {
          cout << tab[k] << " - liczba doskonala" << endl;
        }
      }
    }

    delete[] tab;
    return 0;
  }
}
1

Prawdopodobnie problem jest z **niewłaściwym **( czytaj zbyt wolnym ) algorytmem wyznaczającym wszystkie dzielniki danej liczby.
Zakres pętli może być tutaj **skrócony **.

for( int d = 1; d < sqrt(tab[k]) ; d++)      
1
  1. Użyj vector
  2. Użyj ios_base::sync_with_stdio(false); oraz cin.tie(nullptr);
  3. Nie musisz sprawdzać if(n<1000) oraz if((tab[k])&&(tab[k]<32000)) wszystkie sprawdzarki gwarantują zadeklarowany zakres.
  4. for(int d=1,half=(value>>1);d<=half;++d) (operator <<1 to mnożenie przez 2 tylko szybsze (owszem wszystkie popularne kompilatory ... zwykle nieudolne usprawiedliwienia początkujących))
  5. W sumie dla sprawdzarki nie musisz magazynować danych wejściowych.
  6. Warto używać istream_iterator zwłaszcza gdy wprowadzany jest ten sam typ danych
  7. Kaskada if'ów -> coś nie halo, zawsze.

Po zastosowaniu powyższego mamy:

#include <iostream>
#include <iterator>
using namespace std;

int main()
{
	istream_iterator<int> iin(cin);
	cin.tie(nullptr);
	for(int t=*(iin),value=*(++iin);t--;value=*(++iin))
	{
		/*///
		int sum=0;
		for(int d=1,half=(value>>1);d<=half;++d) if(!(value%d)) sum+=d;
		/*/// jeżeli 0 i 1 są doskonałe
		int sum=(value>0);
		for(int d=2,half=(value>>1);d<=half;++d) if(!(value%d)) sum+=d;
		//*///
		static const char *msg[]={"deficytowa","doskonala","nadmiarowa"};
		cout<<value<<" - liczba "<<msg[1+(sum<value)-(sum>value)]<<endl;
	}
	return 0;
}
1

Napisałem w (klik)
(bom dawno w C nie pisał)

sumaDziel(N)={
	my(f=factor(N));
	prod(i=1,#f~, 
		(f[i,1]^(f[i,2]+1)-1) / (f[i,1]-1) )  }

sp={
	[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 
	59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 
	127, 131, 137,	139, 149, 151, 157, 163, 167, 173, 179 ]};

deco(N)={
	my( tmp, d, suma=1);              \\ zmienne lokalne
	for(i=1, 41, 
		tmp = d = sp [ i ]; 
		if( d*d >N, 
			break()); 
		while( N % d == 0,
			tmp *= d;      
			N \= d );
		if( tmp > d ,
			suma *= (tmp-1) / (d-1) );
		if( N <2, 
			break() ) 
	);
	return(suma); }

test(n)=printsep("\t", n, sumdiv(n,x,x), sumaDziel(n), deco(n))
for(i=1, 30, test(i))

kod można wkleić o tu: https://pari.math.u-bordeaux.fr/gp.html

PARI/GP ma pomocnika do policzenia tej sumy np sumdiv(N, x ,x)

funkcja sumaDziel() pokazuje ideę działania. Da się pisać dość zwięźle.

Zaczyna się od rozkładu na czynniki pierwsze.
Funkcja deco() to właściwa funkcja.
Przygotowałem tablicę 41 liczb pierwszych, dzielimy tylko przez te liczby. 179*179 to więcej niż 32 000.

nasza liczba to: TEX

N = p_1^ {k_1} \ast p_2^{k_2} \ast \cdot\cdot\cdot p_x^{k_x}

wtedy suma dzielników wynosi

\prod _{i=1}^{x} \frac{p_1^{k_i+1}-1}{p_i-1}

kody laTEXowe można wkleić np o tu:

Na końcu mały test działania.
Składnia PARI/GP raczej zrozumimała/czytelna.

Metoda podpatrzona u Pana Robert A. Fox

0

Ok i jaką odpowiedź ten twój kod daje dla liczby 28?
I gdzie w twoim kodzie jest pętla do pierwiastka?

1 użytkowników online, w tym zalogowanych: 0, gości: 1