10 / 20
Jan 2018

Otóż już odpowiadam. Na ideone wyraźnie widać, że twoje wejście i wyjście jest nieprawidłowe. Zmienna ‘t’ oznacza ilość testów, następnie dla każdego testu zmienna ‘n’ oznacza ilość kolejnych liczb (ciąg liczb) przeznaczonych do przestawienia.

Trzecie wejście powinno wyglądać tak:
4 1 2 3 4 lub 8 1 2 3 4 5 6 7 8
Czwarte wejście zaś tak:
5 1 2 3 4 5 lub 10 1 2 3 4 5 6 7 8 9 10

Wyjście dla trzeciego przypadku:
4 3 2 1 lub 8 7 6 5 4 3 2 1
Wyjście dla czwartego przypadku:
5 4 3 2 1 lub 10 9 8 7 6 5 4 3 2 1

Więc program zwyczajnie nie realizuje swojej treści poprawnie. Pierwsza liczba na wejściu każdego zestawu określa ilość kolejnych liczb w zestawie. Problem, może również stanowić funkcja atoi, która nie zawsze realizuje swoje zadanie poprawnie. Ponadto pobierasz wejście jako string i sędzia później może zwracać błąd jeżeli w specyfikacji testu ma ustawione, że wejście powinno zawierać ‘typ liczbowy’ (to tylko przypuszczenie).

Dodatkowo:
Po pierwsze proszę uporządkuj kod (wcięcia), ponieważ mimo, że go rozumiem to czyta się go jak “Pana Tadeusza” i to po mongolsku :slight_smile: Po drugie (przypuszczam, przepraszam jeżeli się mylę) kod niestety nie jest samodzielny. Nie mam tu na myśli średnio-zaawansowanej formy kodu (gdyż każdy jest się w stanie tego nauczyć) lecz niedpowiedni dobór środków do treści zadania. Osobiście uważam, że nie ma co wytaczać ‘armat’ przeciwko ‘prostemu problemowi’. Uwierz da się to spokojnie napisać w 20 linijkach kodu. Nie mówię, że stosowanie klas, wektorów, wskaźników i reszty dobrodziejstw języka jest złe, ale … po co?

Pozdrawiam :wink:

Dziękuję za odpowiedź i naprowadzenie. Część pierwsza: sprawdzę, może faktycznie coś jest nie tak. Część druga: uporządkuję, kod jest samodzielny - przeprosiny przyjęte :wink: a jego treść wygląda jak wygląda ponieważ juz dwano chciałem opanować troche lepiej C++ :wink:

Jeśli chodzi o brak wcięć na samym dole są one wynikiem limitu rozmiaru pliku źródłowego - chyba 5k.

No cóż pierwsza liczba w zestawie nie może być ujemna, ponieważ oznaczałoby to ujemną ilość liczb w ciągu co jest hmm … trudno osiągalne :slight_smile: jeśli chodzi o ‘0’ na początku zestawu to nie widzę przeszkód. Zwyczajnie masz wtedy pusty ciąg liczbowy i taki też zwracasz. Co do wartości już w konkretnym ciągu liczbowym to raczej dowolność.

Jak teraz patrzę na kod to mam małą wskazówkę, staraj się unikać ‘malloc’ i ‘free’ w C++. Są to pozostałości z języka C. Jak ogólnie wiadomo C++ szczyci się mianem języka obiektowago od samego początku swojego istnienia z C jest inaczej. Instrukcjie ‘malloc’ i ‘free’ mogą nie działać właściwie podczas pracy z obiektami i alokacją lub zwalnianiem pamięci dla nich. Powodem tego jest prosty fakt, że podczas ich opracowywania nie kierowano się obiktowością języka. W C++ to raczej bardziej korzysta się z ‘new’ i ‘delete’.

Dziękuję za odpowiedź raz jeszcze. To podsumowując, czy w przypadku liczby ujemnej lub 0 mam wyświetlać pusty wiersz (lub brak wiersza?) czy może po prostu ‘0’ ?

Niestety mimo poprawek uparty i nieprzeku*ny sędzia nie daje się przekonać :wink:

Ponieważ, nadal masz ten sam błąd. Napiszę inaczej albo lepiej podam typowy stdin i stdout jaki powinieneś mieć na ideone.
stdin:

6 - ilość zestawów danych
// teraz podajemy zestawy

pierwszy zestaw: 7 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu 1 2 3 4 5 6 7
drugi zestaw: 3 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu 3 2 11
trzeci zestaw: 4 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu 1 2 3 4 5 6 7 8 (powinny być tylko 4 liczby w ciągu a nie 8) - błąd
czwarty zestaw: 10 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu 5 4 3 2 1 (powinno być 10 liczb w ciągu a nie 5) - błąd
piąty zestaw: 4 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu -1 -2 -3 4 5 (powinny być tylko 4 liczby w ciągu a nie 5) - błąd
szósty zestaw: 10 - ilośc liczb w ciągu liczbowym a potem kolejne liczby ciągu -1 -2 -3 4 5 6 7 (powinno być 10 liczb w ciągu a nie 7) - błąd

stdout:
7 6 5 4 3 2 1
11 2 3
4 3 2 1 - a gdzie 8 7 6 5?
1 2 3 4 5
4 -3 -2 -1 - brakuje ‘5’ na początku błąd
7 6 5 4 -3 -2 -1

Zwyczajnie gubisz liczby z wejścia przez nieprawidłowe zdefiniowanie ich ilości w programie.

No i dalej nic. Mam coś takiego, dla:
6
7 1 2 3 4 5 6 7
3 3 2 11
4 1 2 3 4 5 6 7 8
10 5 4 3 2 1
4 -1 -2 -3 4 5
10 -1 -2 -3 4 5 6 7
mam:
7 6 5 4 3 2 1
11 2 3
8 7 6 5 4 3 2 1
1 2 3 4 5
5 4 -3 -2 -1
7 6 5 4 -3 -2 -1
czyli niezależnie czy podaję (na początku) większą, mniejszą lub równą ilość - dalej nie działa :expressionless:

Nie do końca jestem przekonany czy wiesz jak działa SPOJ i sędzia. Nie wystarczy, że masz dobre wyniki na wyjściu i … ok (po co mi dobre dane wejście?). Twój tok rozumowania wygląda dla mnie tak:

Piszę aplikację do logowania na stronę banku/konto bankowe. Wprowadzam randomowe dane (hasło i login) i … zalogowałem się (nie ważne, że nie na swoje konto) ale się zalogowałem. Wniosek … program do logowania działa w 100% poprawnie.

Sędzia sprawdza wejście i wyjście, które są dla niego równie ważne. Twoje wyjście nie pokrywa się z wejściem więc program działa źle i koniec tematu. Zapewnij mu poprawne wejście i wyjście to sędzia to zaakceptuje.

Osobiste przemyślenia (bez urazy) czytasz na własną odpowiedzialność :slight_smile:
Niestety utwierdza mnie to w przekonaniu, że kod albo nie jest samodzielny lub używasz zaawansowanej składni omijając podstawy (nie mnie to oceniać dokładnie). Dobry programista (ba nawet początkujący programista) stosuje metody i składnię dobraną do poziomu zadania - chcesz być dobrym programistą, prawda? Powiem więcej, dopóki nie siedzisz w głębokiej developerce nie wykorzystasz większości zagadnień języka. Można korzystać z wielodziedziczenia, wskaźników na wskaźniki do tablic wielowymiarowych, makrodefinicji czyli zmiennych i funkcji definiowanych w makrach, szablonów, przeciążania operatorów, operacji na rejestrach w pamięci, wyjątków, głowić się nad tym czy tu zadziała wczesne czy późne wiązanie, bawić się wielowątkowością (bo czemu nie?), odwijać stos … tylko po co? Wygląda to niestety tak jakbyś nie potrafił zmienić kodu aby wejście ‘wyglądało poprawnie’. Co jeszcze, skoro chcesz używać zaawansowanej składni to czemu nie iść w kodzie na całego zadbaj też o drobiazgi? Post in/dekrementacja są wolniejsze od prefiksowej wersji, nadal używasz malloc i free w C++, używasz funkcji ‘atoi’ gdy masz ‘stoi’, wskaźniki? może referencje byłyby lepsze?

Kod machnięty w 30-40 sekund:
Prosty kod12

Nadal (mimo wskazówek) pobierasz wejście jako string a może sędzia akceptuje na wejściu tylko typ liczbowy?

Dzięki za wyczerpującą odpowiedź :sunny: Właśnie, może faktycznie tutaj chodzi o to że ciągiem wejściowym jest typ string. To może być dobry trop. Co do kodu, to tak jak wspomniałem wyżej ‘ucze się’ C++ a swoje lata już mam gdzie wcześniej pisałem trochę w C. Może dlatego zostały mi te operacje :slight_smile: dzięki nim kod waży w pamięci mniej a tutaj widzę że mogę na spoju grzecznie ‘pobawić się’ ogólnym językiem robiąc coś pożytecznego :slight_smile: Tak jak mówię, dzięki za odpowiedź i za pojęcia dotąd mi nieznane (m.i. ‘odwijać stos’ (pierwsze słyszę)). To jest mój debiut z językiem i sądzę że prędzej czy później z braku czasu przestanę bawić się w ‘programowanie bliżej sprzętu’ i zacznę pisać normalny kod :slight_smile:

z takim talentem do gmatwania prostych rzeczy (kod dłuższy 20-30 razy dłuższy niż wymagany) zmarnujesz się jako programista - zacznij raczej pisać wielotomowe cykle powieściowe (sagi ?) lub scenariusz telenowel :slight_smile:

Ale jeszcze nie jutro? :wink:

BTW
W zasadzie masz już to zadanie zaliczone na AC, więc może już Cię nie interesują uwagi na jego temat. W twoim kodzie trudno cokolwiek znaleźć [znaleźć błąd] . Pisanie programów w C++, używając klas jest jak najbardziej wskazane, bo właśnie między innymi w taki łatwy sposób można się tego nauczyć, programowania obiektowego z “klasą” :wink: , na prostych programach [programikach] na SPOJ’u. Jednak klasa to nie worek [na śmieci ;-)] , do którego wrzuca się wszystko, tak samo jak nie jest takim workiem funkcja, do której wrzuca się cały program, nie zależnie czy tą funkcją będzie main () czy start().

Po to właśnie, żeby się [na]uczyć {C++], ale jeżeli ktoś woli pozostać przy “starym” “gołym” dobrym C, to jego wolna wola ale niepowinien zniechęcać do tego innych. I to prawda, że do zaliczenia zadań na SPOJ’u wystarcza C, ale chyba jedynym celem nie jest tylko i wyłacznie AC?

Nie ma to żadnego znaczenia. Wejście jest plikiem tekstowym - ciąg znaków askii i program sędziujący nie interesuje się jak wejście jest wczytywane, interpretowane i przetważane przez testowany [sprawdzany] program. Liczy się tylko i ważne jest wyjście, zapisywane do pliku tekstowego, a więc znowu zwykłe proste znaki ASCII i dopiero program sędziujący robi z tego pliku odpowiedni użytek.

jak widzę:

const char* convertstringtorightformat(const char *sp, int delimiter){const char *p, *q;char *s, *t;int length, first = 1, index = 0, temp = 0;s = trimstring(sp);q = p = s;while(*q++ != ‘\0’){if(*q == delimiter){q++;}};length = q - p;t = (char *)malloc(sizeof(char) * length);while(p != q){if(*p == delimiter){if(first == 1){first = 0;memcpy(&t[index], p, sizeof(char));}while(*p == delimiter){temp++;p++;}if(temp > 0){p–;}} else {first = 1;memcpy(&t[index], p, sizeof(char));}index++;p++;}return t;}

To aż mam ochotę powtórzyć klasyka sprzed kilkudziesięciu lat: https://www.youtube.com/watch?v=0GOfcarW3uw#t=00m21s4 :wink:

Drugie z pewnością :wink: Słuszną uwagę podał nieco niżej @mariusz193 :wink:

Nie machaj shortów. Kod będzie lepszy i gotowy w 20-30 sekund :wink:

Oj… :wink:

Z innych ciekawych rzeczy:

@narbej zawsze był takiego zdanie, co oczywiście szanuję, ale pozwolę sobie (znowu) nie zgodzić się z teorią, iż SPOJ może służyć do nauki jakiegokolwiek języka na wysokim poziomie - truizmem będzie choćby SQL. Polecam mój monolog i lekturę forum. Ostatnio sam zostałem (bardzo ostro) skrytykowany przez osobę, którą próbowałem uświadomić, że za wiele mądrości i intuicji nie wyciągnie swoimi problemami konceptualnymi dotyczącymi trywialnych problemów, których nie umie precyzyjnie przedstawić - niezależnie od tego jak dużo cudów w ifach, randów na poziomie kryptografii czy nawet szablonów użyje. W każdej nauce intuicje są bardzo cenne, ale są pewne granice - nie można być biologiem goniąc pod mikroskopem po raz enty żyjątka w kropli wody z kałuży i nie można być informatykiem siedząc nad entym zadaniem na SPOJu (albo entym wymyślonym samodzielnie problemem, który nie ma nic wspólnego ze współczesnym światem). Raz, drugi, trzeci, może nawet szósty - ok, ale potem może to być świetną rozrywką a nie czymś rozwojowym. Gdy jakiś ćwiczeniowiec / nauczyciel każe przygotować implementację stosu przy użyciu klas i wskaźników w C++, robi to właśnie w celu wyrobienia intuicji - w przyszłości stos będzie się na szybko implementowało w tablicy albo korzystało z bibliotek.

Tymczasem dużo osób próbuje na SPOJu nauczyć się programowania na wyśrubowanym poziomie, co na ogół przynosi marny skutek. Spora część uznaje za “umieć język” niskopoziomowe fastIO i pisze potwory, bo przecież cin jest wolny, scanf wciąż za wolny, a jakieś inline cośtam oparte na pointerach i getchar_unlocked() świetne. W efekcie mamy specjalistę ds ręcznego odwijanie pętli, pisania własnych sortów, nie uznawania STLa itd. Taka osoba nie umie programować tylko żyje w błędnym przeświadczeniu, że programowanie to nie używanie stringów na rzecz char[], a dobrego programistę można poznać po czasie nie większym niż 0.01 s na polskim SPOJu.

Drugi typ ludzi, który spotykam (ostatnio) częściej niż opisany powyżej, myli SPOJa z projektem łazika marsjańskiego z funkcją googlowania i tweetowania, a także automatyczną obsługą profilu na fb. Tacy ludzie wszędzie widzą C++20 jak nie C++400, nie uznają niskiego poziomu i sądzą, że “umieć programować” to rozwalić trudne zadanie na SPOJu wykorzystując vector zamiast tablicy, trzydzieści klas wewnętrznych i anonimowych, szablony itd. Część z nich nie uznaje konstrukcji:

int x;
cin >> x;

bo przecież więcej wiedzy uzyskuje się z:

int* x = new int;
cin >> *x;

W obu przypadkach kończy się to jednak równie źle. Pierwsi ludzie nie umieją programować, bo programowanie to technologia, a technologia - czy to się komuś podoba czy nie - musi być najnowsza. Omawiany przypadek przypomina rolnika nie uznającego traktorów, bo konie są bardziej naturalne albo mechanika, który karierę zakończył na maluchach. W drugim przypadku ludzie również nie umieją programować, bo każda technologia ma swoje zalety i wady oraz - czy to się komuś podoba czy nie - musi być używana adekwatnie do zaistniałego problemu. Tymczasem takie osoby cierpią na ten1 problem tylko w nieco bardziej egzotycznej postaci - w życiu nie wychodzą poza pracę z jednym plikiem (wszak to SPOJ), a sądzą, że gry 3D są w zasięgu ich umiejętności. I kończy się to marnie, bo przy pierwszym projekcie wychodzi na jaw fakt, że na SPOJu nie nauczyły się tak na prawdę niczego…

Nie miałem na myśli takiej formy nauki, jaką opisałeś. Może po prostu źle się wyraziłem. Miałem na myśli raczej utrwalanie i doskonalenie [na SPOJ’u] tego czego możesz i powinieneś nauczyć się w dobrej książce. Taki prosty przykład. Wiele dobrego słyszałem o pewnym języku programowania, o którym nie miałem zielonego pojęcia, a miałem blade i używałem już “na codzień” C/C++. Fajnie się czytało i wszystko było zrozumiałe na przykładch w skrypcie do nauki tego języka. Schody zaczęłyt się, gdy chciałem zastosować zdobytą wiedzę do rozwiązania nawet najmniejszego problemu na SPOJ’u. I właśnie to i tylko to miałem na myśli mówiąc o nauce programowania na SPOJ’u. Testowanie i wykorzystywanie swojej [świeżo] zdobytej wiedzy na praktycznych przykładach do ich rozwiązywania. Oczywiście nie mają one wiele wspólnego z rzeczywistością, z rzeczywistymi problemami ale od czegoś trzeba zacząć.

Nie podobało mi się i nadal nie podoba, że ktoś, kto do rozwiązywania zadań na SPOJ’u używa tylko [tu wstaw odpowiedni język, metodykę], mówi/pisze/zaleca innym czego mają używać a czego nie.

I na koniec, zacytowałeś na początku fragment kodu pytającego pisząc: “jak widzę:”. Trzeba było jeszcze przeczytać jego wyjaśnienie czemu to tak zrobił. A że jego klasa jest reklamą i przykładem jak tego nie powinno się robić to już inna sprawa, przecież dopiero się uczy i może należałoby tutaj mu pomóc, a nie pisać że ma 20 czy 30 razy [niestety to prawda] za dużo kodu :wink: Ale do tego, aby pomóc, trzeba mieć już trochę większe niż blade pojęcie o klasach czy sposobie działania samego SPOJ’a :wink:

Wg mnie na forum najbardziej może pomóc mnogość opinii i komentarzy, o ile oczywiście nie stanowią one spamu :wink: Odpowiednio ambitna jednostka przeczyta je i wyciągnie wnioski, a co najważniejsze - będzie miała świadomość, że w danej dziedzinie nie ma jednego obowiązującego komentarza załatwiającego cała sprawę :wink:

nie zajmuję się (nie mam takich ambicji ani zainteresowań):

  1. nauką programowania w C/C++
  2. nauką algorytmow

głównie podaję przykłady, dla których dany program będzie działał niezgodnie z warunkami zadania

i tylko w wyjątkowych wypadkach piszę opinię o programie - głownie na prośbę zainteresowanego i wyjątkowo, gdy patrzenie na program mnie już boli :slight_smile:

Ogólnie, to wszystko co zostało tutaj napisane jest prawdą mimo różnych opinii na ten sam temat, czyli programowanie w praktyce :slight_smile: Ja osobiście uważam, że rozwiązanie danego zadania, powinno być dobrane do stawianego problemu. Omawiane zadanie plasuje się jako łatwe, co prawda można je rozwiazać pisząc np. klasę o 20k linijkach kodu (bo czemu nie, rozwiązań znajdzie się pewnie tyle ilu będzie programistów) tylko bedzie się to mijać z celem przynajmniej dla mnie. Ja wpadam na SPOJ nie tyle aby nauczyć się programować co pobawić się w wolnym czasie zamiast siedzieć na FB, YT czy stronach z memami. Do nauki wektorów, klas i obiektowości ogólnie bardziej wolałem i polecam zrobienie własnego projektu typu prosta gra, program użytkowy, ponieważ tam lepiej zauważymy wpływ i zastosowanie obiektowości w kodzie.

Pozdrawiam