217 / 277
Jan 2020

Witam! Czy jest ktoś kto umiałby mi wytłumaczyć dlaczego sędzia tego nie zalicza chociaż w kompilatorze wynik jest poprawny. Z góry dziękuje za odpowiedź.
#include
#include

using namespace std;
int liczba, dzielniki;
int main()
{
cin>>liczba;
if(liczba>=2)
{
for(int i=1;i<=liczba;i++)
if((liczba%i)==0)
{
dzielniki++;
}
}
else
cout<<“NIE”;
if(dzielniki>2)
{
cout<<“NIE”;
}
else cout<<“TAK”;
return 0;
}

sędzia zadania nie zalicza, ponieważ wyniki twojego programu są inne, niż oczekuje (czy inaczej mówiąc: złe)

wskazane jest przekazywanie kodu poprzez ideone.com2 - nie ginie wtedy formatowanie kodu ani jego fragmenty
na ideone.com2 należy też testować program, co najmniej dla danych przykładowych podanych w zadania - zobaczyłbyś wtedy, że wyniki z twojego programu są niewłaściwe

6 months later

chyba zapomniałaś o ; przy tak i nie oraz osobiście usunełabym te < i else przeniosła na nowa linie

2 months later

Dobry wieczór

Nie chcę zaśmiecać i otwierać nowego tematu, więc tutaj zapytam - czy ktoś mógłby wytłumaczyć, czemu sędzia nie zalicza? Program działa, przetestowałem i nie znalazłem dziur, natomiast u sędziego wyskakuje błędna odpowiedź.

#include
#include <math.h>

using namespace std;

int main()
{
int i, dzielnik, liczba,j;
int pierw;
int spr = 1;
cin >> j;
if (j > 100000)
{
return 0;
}

for (int k=0; k < j; k++)
{


cin >> liczba;
if (liczba > 10000 || liczba == 1)
{
    return 0;
}
pierw = sqrt(liczba);

for (i = 2; i <= pierw; i++)
{
    dzielnik = liczba % i;
    spr = spr*dzielnik;

}

if (spr == 0)
{
    cout << "NIE";

}
if (spr != 0 || liczba == 2)
{
    cout << "TAK";
}
spr = 1;
}

return 0;

}

Spróbuj może test z zadania to wtedy powinieneś zauważyć błędy w linijkach:

Jeśli sprawdzana jest liczba 1 to wychodzisz z programu :thinking:
Cały ten if jest niepotrzebny bo autor zadania …

oraz

powinien być jeszcze “znak końca …”

Podejrzewam, że ta konstrukcja jest nieprawidłowa, chociaż nie mogę znaleźć konkretnego przypadku dla którego będzie źle. (jakieś dziwne przepełnienie) Trzeba posprawdzać dokładnie dla kilku pierwszych wartości.
Czy nie jest mylące nazwanie zmiennej będącej reszta z dzielenia dzielnik :grinning:

Z tego co wiem, liczba 1 nie jest ani liczbą pierwszą, ani liczbą złożoną :D. Czyli wychodzenie z programu wydaje mi się zasadne, bo ma badać czy liczba jest pierwsza czy nie i ma się wyświetlać tylko “TAK” lub “NIE”. Co powinno zatem wyświetlić się w przypadku 1?

Tak czy siak, nawet po wyrzuceniu tego ifa i dodaniu “endl” sędzia odrzuca rozwiązanie, a ja nie wiem dlaczego. Jakiś pomysł? :smiley:

Pewnie masz rację, chociaż nie jestem matematykiem. Zauważ natomiast, że w zadaniu autor się pyta o to czy liczba jest liczbą pierwszą [TAK], czy nią nie jest [NIE]. Natomiast nie obchodzi go zupełnie czy jest złożoną czy nie :wink: czyż nie? Dodatkowo przyjżyj się uważnie przykładowi w zadaniu EXEMPLE i outputowi. Czy autor dla 1 [jedynki] “wychodzi” czy nie?

Ta dziwna konstrukcja, przy każdej większej liczbie pierwszej, będzie “dawała” dowolnie duże wartości, dużo większe od maxInt.Można by powiedzieć, że ta konstrukcja bardzo przypomina konstrukcję n! [n silnia], ale oczywiście nią nie jest.

Praca domowa dla chętnych, przy jakiej najmniejszej liczbie pierwszej nastąpi przepełnienie INT.? :wink:

No i drobne uwagi.
W C++ nie używa się match.h tylko cmath
Zamiast liczyś sqrt, można np tak:

for (i = 2; i*i <= liczba; i++)

i wtedy biblioteka cmath jest zbędna.
Warto testować swój kod na ideone.com1: https://ideone.com/Dhn0yD1, a także czytać wątek [wiem, że długaśny] a nie tylko się przyklejać [bardzo dobrze, że dbasz o środowisko i starasz się nie zaśmiecać]

Powinno wyswietlic sie “NIE”. Na przyklad:

  if ( liczba == 1)
    {
        cout << "NIE"<<endl;
        continue;
    }

Znalazlem w miare duza liczbe- 7727 jest liczba pierwsza. Program zwraca “NIE”, wiec konstrukcja jest zla. Mozna zrobic instrukcje warunkowa sprawdzajaca reszte z dzielenia, a nie mnozyc.

Przepelnienie int powinno nastapic dla 13! (bo rzeczywiscie w zmiennej spr liczona jest jakby silnia). Ale konstrukcja jest jak widac madrzejsza ode mnie :rofl: (na pewno dobrze rozpoznaje liczby pierwsze do 1000- zabraklo mi cierpliwosci zeby przekleic wynik dla 10000 wartosci z ideone)

TZn To było tylko takie skojarzenie na szybko. Dokładnie spr jest iloczynem reszt z dzielenia a te reszty, dla liczby pierwszej są różne od zera i dla dużej liczby pierwszej mogą być coraz większe np
x %2 = 1
x %3 = [1,2]
x%4 = [1,2,3]
x%5 = [1,2,3,4]

x%100 = [1…99]
dla x >= 10000

Dodatkowo nie jestem pewny, czy każde przepełnienie, spowoduje wyzerowanie zmiennej spr.

Jak rozumiem Panowie, owo przepełnienie sprawia, że zmienna spr po osiągnięciu odpowiednio dużej wielkości zeruje się, ponieważ nie ma w niej miejsca tak? W takim wypadku wystarczy, żebym wykonał taką instrukcję:

long long int spr = 1;

I wówczas miejsca jest wystarczająco. Ostatnią liczbą pierwszą przed 10 000 jest 9973 i ta liczba jest wskazywana przez program jako pierwsza (przetestowałem to). Mimo to, sędzia wciąż odrzuca odpowiedzi. Dlaczego? :frowning:

EDYCJA:

Ok, był błąd dla jedynki (wyskakiwały dwa komunikaty), ale udało mi się go zażegnać. Mimo tego, sędzia wciąż wskazuje błąd. Wklejam cały program, ponieważ przeszedł pewne zmiany, a już skończyły mi się pomysły, gdzie jest coś nie tak:

#include
#include <math.h>

using namespace std;

int main()
{
int i, dzielnik, liczba,j;
int pierw;
long long int spr = 1;
cin >> j;

for (int k=0; k < j; k++)
{
cin >> liczba;

pierw = sqrt(liczba);

for (i = 2; i <= pierw; i++)
{
    dzielnik = liczba % i;
    spr = spr*dzielnik;

}

if (spr == 1 && liczba ==1)
{
    cout << "NIE" << endl;

}

if (spr == 0)
{
    cout << "NIE" << endl;

}
if ((spr != 0 && liczba!=1) || liczba == 2)
{
    cout << "TAK" << endl;
}
spr = 1;
}

return 0;

}

Jak widzę tak wstawiony kod to moja chęć pomocy spada o 99%. Typ long long int jest za mały. Nie szukaj dalej. Nie ma sensu wykonywać działań po przepełnieniu inta.

W takim razie nie pomagaj, skoro aż tak Cię to razi. Wklejam na Ideone, tak jak mi zalecono i daję kopiuj. Takie coś otrzymuję.

Jeżeli jest za mały, dlaczego program wypluwa poprawne wyniki?

Prawie się zgadzam z @hipcia w całej rozciągłości i w prawie 100%, ale u mnie niechęć sięga 99,9%. Nigdy jeszcze nie widziałem takiego podejścia do tego zadania, więc może to dobrze? :wink: Jeżeli nie int i nie long long to zostają jeszcze do przetestowania float, double i long double. Tak naprawdę to wystarcza tu typ bool, ale jak nie wiesz jak to zrobić …

Mimo wszystko gratuluję samodzielności [z małą pomocą forum]. I moje rady:
Naucz się poprawnie wklejać kod lub korzystaj z ideone.com !!! No i może przeczytaj w końcu: Jeśli zaczynasz, przeczytaj koniecznie! <-- to jest link,w który musisz kliknąć.

@narbej Faktycznie zmiana na double to znakomity pomysł :slight_smile: Program zostanie zaliczony chociaż metoda mogłaby być szybsza z boolem.

Cóż, powiem nieskromnie, że wiem :wink:

Tzn, wiem, że zostanie zaliczony. Po prostu pisząc że zostały do przetestowania, równolegle przetestowałem te opcje w tym samym czasie [no może odrobinkę wcześniej], bo inaczej bym o nich nawet nie wspominał.
Bo pomysł nie jest znakomity, to tylko taka tam proteza czy obejście, wybrnięcie z problemu. Rozwiązań jest tu multum prostszych, ale okazuje się, że jest też i taki jak wyżej sposób i @dodename_1 będzie mógł się cieszyć kolejnym AC.

Hej! Rzeczywiście zmiana na double zadziałała!

Co do innych rozwiązań - to też podsunął mi kolega, ja miałem nieco inne, ale to mi się bardzo spodobało. Trwałem przy programie, ponieważ nie znam rozwiązań ze zmienną “bool”, a nie chciałem bezmyślnie kopiować innych schematów, tylko oprzeć się na szkielecie programu, do którego udało mi się samemu dotrzeć i poszukać pomocy u innych, bardziej doświadczonych użytkowników w tych miejscach, których nie rozumiałem.

Wszystkim bardzo dziękuję za pomoc! :slight_smile:

Gratulacje zaliczenia zadania, jednak myślę, że warto byś jednak spróbował rozwiązania z typem bool.
Zresztą nie musi to być typ bool, wystarczy typ int.
Podpowiedź:
int p = 0;

for(){

if(coś tutaj)
p=1;
}
if(p )

else

p=0;
To jest oczywiście tylko szkielet

Metoda z typem double chociaż tutaj przeszła, jest moim zdaniem takim rozwiązaniem zastępczym. Poza tym wydaje mi się, że mogłaby już niedobrze pracować dla większych liczb np. dla liczb bliskich 1000 000 000 podejrzewam, że będzie wykazywać, że nie ma tam liczb pierwszych.

3 months later

Hej, czy mógłby ktoś zerknąć na kod i podpowiedzieć co mógłbym poprawić aby został zatwierdzony. Generalnie wydaje mi się, że wszystko działa jak powinno ale jak widać coś jest jednak nie tak :smiley:

 int n = int.Parse(Console.ReadLine());
        if (n < 100000)
        {
            for (int j = 0; j < n; j++)
            {
                int a = int.Parse(Console.ReadLine());
                if (a > 0 && a <= 10000)
                {
                    for (int i = 0; i < 1; i++)
                    {
                        if ( a == 1 || a % 2 == 0 && a != 2 || a % 3 == 0 && a != 3) 
                        {
                            Console.WriteLine("NIE");
                        }
                        else
                        {
                            Console.WriteLine("TAK");
                        }
                    }
                }
            }
            Console.ReadKey();
        }

Wszystko działa jak należy? To pochwal się ile i jakie przypadki sprawdziłeś, najlepiej przez link do ideone. Np. co wychodzi Ci dla 25…