Sędzia wywala mi błąd SIGABRT.
Nie mam pojęcia o co chodzi.
http://wklej.org/id/1940773
Ponieważ jest prawie AC, pozwoliłem sobie "trochę uszkodzić link do wklejki. Błąd jest paskudny - dosyć trudny do znalezienia. Podpowiem więc na razie tylko dwie rzeczy. Możliwe, że w twoim środowisku (windows?) przy testowniu jest w miarę ok? Jeżeli tak, to w mainie zakomentuj wywołanie sortowania i wyślij taki "poprawiony" program na SPOJ'a. Już nie będzie SIGABRT ale WA zła odpowiedź. Wniosek - masz skopaną funkcję -procedurę sortowania. SIGABRT to wychodzenie poza przydzielony i dozwolony obszar pamięci.
- Podpowiedź II. Kod jak widzę masz starannie napisany, chociaż dostrzegam małe niekonsekwencje. Błędem jest jeden mały, nadmiarowy średnik. Jak go znajdziesz i usuniesz - AC.
Gdybyś chciał więcej, krytycznych, ale konstruktywnych [mam nadzieję] moich uwag do twojego kodu, napisz.
OK
Dla przypomnienia i dla "potomnych" na czym polegał błąd w twoim kodzie:
Miałeś w funkcji sortowania takie pętle [piszę z pamięci]:
int i, j;
for (i = 0; i < N; ++i); //<== ten średnik to w tym kodzie błąd
{
for (j = 0; j < N-1-i; ++j)
{
I tu od razu niekonsekwencja, o której wcześniej pisałem.
W innych pętlach, używałeś inicjalizacji wewnątrz pętli:
for (int i = 0 ...
Gdybyś zrobił tak, także tutaj, kompilator [przy próbie kompilacji] wypisał by Ci od razu błąd i natychmiast mógłbyś go poprawić.
Nie jestem zwolennikiem nadmiaru nawiasów i wszędzie, gdzie są zbędne usuwam je, zarówno {} jak i ()
Programowanie Obiektowe - tu dopiero raczkujesz, ale ja też
a) zamiast w main() : wsk[j].o=wsk[j].odleglosc(wsk[j].x,wsk[j].y);
mógłbyś napisać tam [w mainie]: wsk[i].odleglosc(); ale musiałbyś zmienić swoją funkcję w klasie na:
void odleglosc() {
o = x*x + y*y; // stosowanie tu funkcji pow() jest niepotrzzebne więc include cmath także jest zbędne
}- Także pozostałe funkcje, a także tablicę wsk, możnaby i warto włożyć do klasy - ale to kiedyś, sam się nauczysz.
PS
W twoim kodzie miałeś średnik na końcu drugiej pętli, ale to nie zmienia faktu, że był/jest to błąd.
Ja zawsze staram się pisać pętle tak:
for (......) { //tu od razu nawias otwierający gdy potrzebuję nawiasów.
.....
.....
}
PS 2
Po takich poprawkach, po kompilacji, prawdopodobnie nic się nie zmieni w szybkości działania czy tym bardziej w samym działaniu, ale czytelność napewno będzie lepsza.
Witam
Siedzę nad tym zadaniem już drugi dzień. Wszystkie ekstremalne testy program zalicza prawidłowo a dostaję komunikat "Błędna odpowiedź. Może ktoś zerknąć?
Podejrzewam że autor ma inny algorytm sortujący i te same odległości może wypisywać w innej kolejności... Ale to byłoby strasznie głupie.
Poniżej mój kod
https://ideone.com/YIPxUf105
Dodatkowo jeszcze prawie 3500 sortuje w głupi sposób : http://pl.spoj.com/ranks/PP0506A/54
Co jest w twoim kodzie błędne nie wiem- ale przecież już sam znalazłeś, więc warto to napisać. Takie moje uwagi:
- Czy nazwanie klasą "TABELA", tego co jest prostą strukturą punktu "PUNKT" nie jest błędem chodzi mi szczególnie o nazwę?
- Używanie zmiennych globalnych, gdy można lokalnych.
- Bardzo zaawulowane używanie dodatkowego dodanego miejsca w tablicy jako zmiennej tymczasowej.
- Używanie własnej procedury sortującej - czy na pewno poprawna - gdy są gotowe w STL.
- Używanie zmiennej typu double, gdy do przechowywania odległości [jej kwadratu] wystarczy typ int (max = 2 * 1000^2)
- Sędzia jest surowy [program porównujący odpowiedzi z wzorcem] ale jednak najczęściej bardzo wyrozumiały gdy chodzi o nadmiar lub niedobór białych znaków [space, tab, enter] byle był tam chociaż jeden, dowolny z nich, gdy jest niezbędny.
- Oczywiście sprawdziłem i nie ma pkt w identycznej odległości.
Dziękuję za odpowiedź. Rozumiem że mój kod nie jest piękny stylistycznie ale jakby nie było liczył poprawnie. Błędu nie znalazłem ale zmieniłem sortowanie quicksortem na sort() i teraz program przechodzi. Dlaczego tak jest nie wiem. W każdym razie miałem zaimplementowany normalny algorytm quicksort, który dawał mi poprawne odpowiedzi przy wszystkich testach jakie znalazłem.
Jeżeli Twój kod nie dostał AC to znaczy, że jednak gdzieś jest błąd. Trudny do znalezienia, ale na pewno obecny. W gruncie rzeczy może być wszędzie - jak zauważył narbej, Twój kod jest strasznie zawiły i nie trudno w nim o pomyłkę dla jakiegoś dzikiego testu. Ja dostałem AC pisząc własne sortowanie bąbelkowe. Chyba wyczytałem na forum, że to wystarczy.
Ciekawostka! Raczkowałem wtedy w obiektówce i stworzyłem takie coś:
struct pkt {
public:
string str;
int x,y,o,i;
};
Widzę tu w najlepszym przypadku lukier składniowy na literę p a w najpewniejszym dowód niewiedzy programisty
Mój kod daje błędną odpowiedź. Ja nie widzę błędu i moje testy działają. Może ktoś inny go wyłapie.
http://wklej.org/id/2781980/45
a po co ci kilkanaście losowych testów ?
do znalezienia błędu z zasady wystarcza jeden test, dla którego masz błędne wyniki
jeżeli naprawdę chcesz testować swój program na losowych danych to sam sobie napisz generator, a na czas testowania uzupełnij testowany program o wyprowadzanie odległości punktu od środka układu współrzędnych - wtedy od razu widać, czy wyniki są poprawne
Debugowanie to jedna z najbardziej żmudnych i najważniejszych części pracy nad dowolnym programem komputerowym. Nie tak dawno napisałem sobie Sokobana - skurczybyk zaczął pchać ścianę a potem stał się niewidzialny
Testy podstawowe (zakładam, że chodzi CI o przykładowe wejście i wyjście) są złe gdy nie są proste. Ich celem jest pomoc w zrozumieniu sensu zadania a nie dostarczenie materiału do testów. Powiem więcej - raczej rzadko ma się do czynienia z sytuacją, że testy przykładowe albo zbliżone do nich służą do oceniania poprawności i wydajności programu.
http://pl.spoj.com/problems/DAPPLES/28
Test przykładowy jest prosty. To zadanie wraz z rozwiązaniem i testami jest dostępne na stronie zasugerowanej na samym dole zadania w części "Pochodzenie". Jeżeli chcesz to poświęć przyjemnosć myślenia nad tym problemem i poszukaj testów a zobaczysz wręcz kosmiczne różnice między banałem zasugerowanym w przykładzie a tym, z czym program będzie się musiał zmierzyć. Wiele osób nie zdaje sobie sprawy z faktu, że testy są możliwie złośliwe i uwzględniają najmniej przychodzące do głowy przypadki.
Oczywiście nie musisz tworzyć aż tak rozbudowanych testów. Chyba, że masz czas na ich ręczne rozwiązywanie Niemniej jakieś testy warto mieć.
Po tej moralizatorskiej gadce wezmę pod uwagę fakt, że jesteś początkujący i podam Ci jakiś prosty wymyślony na szybko test
In:
2
1
Camelidae 123 321
5
LAMA 0 0
Alpaczka 999 1000
gUaNaKo -1000 -1000
Wikunia 1000 -10
wigon -100 1000
Out:
Camelidae 123 321
LAMA 0 0
Wikunia 1000 -10
wigon -100 1000
Alpaczka 999 1000
gUaNaKo -1000 -1000
Z C++ mam doświadczenie 2 lata. Stworzyłem silnik 2D i jestem w trakcie robienia gry. Wiem także, że debugowanie jest integralną częscią projektu do wykrywania błędów czasu działania(runtime errors). Także nie jestem takim początkującym, ale przede mną jeszcze długa droga
Co do testów. Wszystkie, które napisałeś program przechodzi. Na ideone dostaję błąd alokowania(std::bad_alloc) przez co program nie przechodzi na spoju. Chciałem się upewnić czy algorytm jest na pewno poprawny i teraz jestem w stanie powiedzieć, że tak. Nie mogę niestety znaleźć za pomocą debugera błędu. W Visual Studio 2015 program uruchamia się bez zarzutów. Zatem jestem zmuszony wkleić kod, który jest prawie AC
Kod tutaj: AC
Mógłbyś looknąć ?
PS.
Musiałem dodać do input'u znak nowej linii, bo takie jest wymóg w treści zadania.
Czy na pewno? Gdyby tak było, na spoju miałbyś błąd sigsegv czy coś podobnego, a przecież masz tam błędną odpowiedź.
Po prostu odległość od pkt (0 0) liczy się tak: odległość = sqrt(x*x + y*y)
można też użyć funkcji: hypot(x,y).
Do celów porównywania odległości, można zrezygnować z obliczania pierwiastka i porównywać kwadraty odległości. Natomiast to co Ty porównujesz, to ... właśnie, właściwie nie wiem i może tu leży pies pogrzebany?