208 / 277
Apr 2019

Moje wskazówki:

  1. Niepotrzebnie wypisujesz "Podaj liczbę: ". Kod sprawdzany jest automatycznie i musisz dostosować się do
    formatu we/wy opisanego w zadaniu, bo inaczej dostaniesz WA.
  2. Nie wczytujesz liczby określającej liczbę przypadków testowych - musisz ją wczytać a potem uruchomić pętlę dla
    testów. Ty wykonujesz tę pętlę zawsze 100000 razy.
  3. Wystarczy sprawdzać dzielniki od 2 do pierwiastka z n. (int j = 2; j*j <= n; j++). Gdy tylko znajdziesz dzielnik możesz
    opuścić tę pętlę, bo liczba będzie złożona.
  4. Musisz rozważyć sytuację gdy liczba to 0 lub 1 - bo to nie są liczby pierwsze.

Powyższe wskazówki pozwolą Ci na uzyskanie AC. A oto bardziej ogólne porady:

  1. Najoptymalniejszym sposobem na to zadanie jest sito Erastotenesa - jak już pouczysz się trochę to proponuję
    powrócić do tego zadania i zaliczyć je tym algorytmem.
  2. Swój kod przekazuj w formie linku do ideone.com1. Możesz tam wklejać input i testować swój kod.
    Staraj się też poprawić czytelność kodu.
  3. Java ma bardzo wolne I/O. Są dużo lepsze sposoby organizacji I/O - poszukaj na przyszłość.
  4. To zadanie wcale nie jest najłatwiejsze z kategorii łatwych. Poniżej masz linki do kilku bardzo prostych, żebyś mógł
    się oswoić:
    https://pl.spoj.com/problems/PTEST/6
    https://pl.spoj.com/problems/POTSAM/4
    https://pl.spoj.com/problems/MWPZ06X/3
    https://pl.spoj.com/problems/VSR/4

Hmm… Zadanie ze średnią jest bardzo proste z punktu widzenia napisanego kodu, ale jeśli dla kogoś kto ma problemy z fizyką (a takich jest wielu) to zadanie nie musi być bardzo łatwe :slight_smile:

Ale sprawdziłem że kolega blackfoo ma jako instytucje wpisany Uniwersytet Warszawski, więc zakładam, że powinien
sobie poradzić

Dzięki wielkie za odpowiedzi i cenne rady :slight_smile: Faktycznie, muszę zwrócić większa uwagę na treść zadania. Kiedyś liznąłem 1 semestr C++, ale było to dawno i wszystko zapomniałem. Teraz studiuje na Wojskowej Akademii Technicznej (ang. Warsaw Univeristy of Technology), tylko ucięło końcówkę.

9 days later

Witam Czy jest jakaś dobra dusza która programuje w Jave i wyjaśni mi co w moim kodzie nie działa ? Programuje od kilku dni i brakuje mi doświadczenia dlatego zgłaszam się do mądrzejszych :smiley:

import java.util.Scanner;

public class LIczbyPierwsze {

public static void main(String[] args) {


    int b = 1;
    int c = 0;

    Scanner lPierwsza = new Scanner(System.in) ;
    int a = lPierwsza.nextInt();

    int g = a+1;
    for ( int i =1;i<g;i++)
    {
        if (a%i==0){
          c = b++ ;
        }
    }

    if (c==2){
        System.out.println("TAK");
    }else{
        System.out.println("NIE");
    }


}

}

13 days later

RESULT: “Błędna odpowiedź”. Proszę o pomoc z jakiego powodu dostaję błąd. Kod sprawdza liczby pierwsze prawidłowo.


#include
#include <math.h>

using namespace std;

int t, i;
int a, m, w;
string odp;

int main()
{
cin>>t;
while((t<=0) || (t>100000))
{
cin>>t;
}

for(i=0; i<t; i++)
{
    cin>>a;

    while((a<=0) || (a>=10000))
    {
        cin>>a;
    }

    odp="TAK";

    for(m=2; m<=sqrt(a); m++)
    {
        w=a%m;
        if(w==0) odp="NIE";
    }

    if(a==1) odp="NIE";

    cout<<odp<<endl;

}
cout<<endl;

return 0;

}

Pomyliłeś się w sprawdzeniu, które nie było wcale potrzebne:

while((a<=0) || (a>10000))

Poza tym tam można by użyć pętli do … while żeby uniknąć redundancji kodu.

Mam kilka uwag. Sprawdzanie czy liczba jest pierwsza możesz wydzielić do osobnej funkcji. Nie używaj zmiennych globalnych. Używanie jednoliterowych nazw jest złym pomysłem - utrudnia czytanie i korzystanie z kodu. Zamiast <math.h> dołączaj < cmath > (raczej nie używamy zdeprecjonowanych/przestarzałych nagłówków z C). Poczytaj o typie bool.

Przykład:

#include <iostream>
#include <cmath> 

bool is_prime(int number)
{
	if (number < 2) {
		return false;
	}
	// ...
}

int main()
{
	int tests;
	std::cin >> tests;
	for (int i = 0; i < tests; i++)
	{
		int number;
		std::cin >> number;
		std::cout << (is_prime(number) ? "TAK" : "NIE") << "\n";
	}
}

Dziękuję za odpowiedź i cenne uwagi. Postaram się przerobić kod i ponownie sprawdzić czy zostanie zaakceptowany.

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.