1 / 23
Apr 2017

Witam! Próbuję rozwiązać to zadanie, szukałem nawet rozwiązań/testów na starym forum, lecz tam wszystkie rozwiązywałem poprawnie. Może Wy zauważycie co jest w kodzie "nie tak".
P.S. Działam na vectorach a nie stringach gdyż tam nie chciało mi się coś wypisać
http://ideone.com/M9q2Ir97

  • created

    Apr '17
  • last reply

    Jan '24
  • 22

    replies

  • 2.2k

    views

  • 10

    users

  • 3

    likes

  • 11

    links

pisanie przez kopiuj, wklej nie jest najlepszą metodą :slight_smile:

sprawdź wynik dla liczby: 161050

Chciałem napisać to samo, ale nie zdążyłem. Więc tylko potwierdzę, metoda copy-paste jest bardzo zła.

PS
Pomoc na forum, powinna polegać, na podaniu wędki a nie rybki, i chociaż jest to trudniejsze i bardziej pracochłonne [dla podpowiadającego] to jednak się postaram :wink:

  1. Testy na forum są często podawane pod konkretny błąd w kodzie pytającego, więc: ".. szukałem nawet rozwiązań/testów na starym forum.." nie jest "usprawiedliwieniem.
  2. W takiego typu zadaniu i rozwiązaniu - program wczytuje po jednej porcji danych i od razu po kolei odpowiada, najlepiej uruchomić swój programik w konsoli i testować z "ręki". Wpisujesz dużą liczbę testów, np 100 i po kolei lecisz 0 [enter] 1 [enter] itd. Po błędnej odpowiedzi programu przerywasz go - wciskając [ctr c],, a w twoim wypadku błąd jest dużo wcześniej, gdy "polecisz" po kolei, przed liczbą 99, czy 161050 :wink:
  3. Gdy masz silną pokusę użyć copy/paste - to zastanów się, czy nie można użyć, jednej funkcji z dodatkowym parametrem: jedena_funckcja(liczba, podstawa) - oczywiście nazwij ją np sys_poz, lub konwertuj itp... i oczywiście możesz przestawić parametry w innej kolejności.
  4. Gdy jedna ulegniesz pokusie, sprawdzaj dokładniej kopię.
  5. Zamiast dziwnych konwersji +48, czy +55, lepiej wstawiać +'0' czy 'A' - 10 itd
  6. AD 5 jeszcze lepiej użyć string konw = "0123456789ABCDEF...." a potem wstawiać wprost push_back(konw[....])
  7. vector 'char' to przecież [prawie?] string, więc też można string.push_back czy też string=string+char a może nawet string = char+string?
  8. Funkcja powinna "robić" całość, więc ewentualnie odwracanie a także działać dla liczby równej 0
  9. ad 8 jak? do { ......liczba /= baza} while(liczba >0) - w ten sposób nawet dla zera raz się wykona, czyż nie?,
  10. Wtedy w main wystarczy
    cin >> liczba;
    cout << konwer(liczba, 16) << ' ' << konwert(liczba, 11) .......
  11. PS 2

  12. W pytaniu warto umieszczać też link do swojej listy zgłoszeń do zadania.

  13. A na ideone wklejać swoje testy w okienko stdin.

2(2). Nawet bym nie pomyślał, że się wykładam na takich liczbach, pomysł rzeczywiście ciekawy i pewnie uchroni mnie w przyszłości przed zaśmiecaniem forum :smiley:
3(3). Liczyłem, że tak będzie trochę łatwiej...no i nawet nie pomyślałem o takim rozwiązaniu :o
5(5). Tego troszkę nie rozumiem...w sensie mam podstawiać konkretne chary zamiast wywoływać je z kodów ASCI? To nie wydłuży tylko kodu?
6(6). Pomysł ciekawy, ale czy, Twoim zdaniem, coś się uda ugrać z tym kodem, który wyskrobałem, czy jest w nim jednak taki błąd, którego nie przejdę?
7(7). Tego punktu nie rozumiem...chodzi o to, żeby zapisywać elementy od początku stringa zamiast na jego końcu?
8(8). Teorytycznie tak, lecz w zadaniu jest zaznaczone, że liczba jest 1<=n, wtedy SPOJ nie powinien się czepiać przykładu, kiedy jest 0, tak?
12(12). Tutaj jest link http://pl.spoj.com/status/SYS,nikusek007/17 Z tego da sie cos wyczytać poza tym, jak szybko się "poddałem"? :slight_smile:

  • Czy nie lepiej było by napisać uniwersalną procedure konwersji ?
    Coś w rodzaju
    vector < char > ConvertToSys( int Value, int Base )

  • Wywołujesz wtedy
    cout << ConvertToSys( Liczba, 16) << ConvertToSys( Liczba, 11) << endl;

  • Przydała by się też procedura która konweruje tobie stringa/tablice znaków na liczbe binarną .
    Wtedy wywołanie
    if ( CharToBin( ConvertToSys( Liczba, 16) ) == Liczba ) i już masz procedure testująca która wykryje ewentualne błędy bo da się zrobić testy dla wszystkich możliwych przypadków jakie mogą pojawić się na wejściu .

Pozwól, że od końca i może nie na wszystko.

Ad 12
Dokładnie tak, czy nie za szybko się poddałeś, a więc czy warto Ci pomagać :wink:.
Ale także, natychmiast znajduję samo zadanie [treść] klikając w nazwę zadania na tej stronie. A klikając [tu w dwukropek] szybko się orientuję, że to nie jest pierwsze twoje zadanie na spoju, także, mniej ważne, dane o Tobie..
Oczywiście znalazłem to wszystrko okrężną drogą już wcześniej :wink:

AD 8
Rzeczywiście, nie zauważyłem, ale po prostu w twoim kodzie w takim razie [też] niepotrzebnie to sprawdzasz. [if(a==0)]

AD 7
Liczbę konwerujesz od końca, więc na koniec, albo musisz zrobić reverse[odwrócenie] stringa [tablicy], albo od razu zapisujesz odwrócone. Każde zadanie, można rozwiązać na wiele sposobów...

AD 6
W twoim kodzie jest tylko jeden błąd, tak mi się wydaje, który powinieneś znaleźć - mój pkt 4. Więc wystarczy trylko go znaleźć i AC?

PS
Właśnie poprawiłęm ten jedyny błąd, wysłałem i jest AC.

PS 2
Podpowiedź @loginus 'a jest jak bardziej ok, sam też myślałem o takim podpunkcie w moich podpowiedziach, ale jakoś zapomniałem :wink: Procedura sprawdzająca,jednak, to:
charToDec(string, baza) - gdzie baza to baza wejściowa. Baza wyjściowa to 10.
Czyli:
if ( CharToDec( ConvertToSys( Liczba, baza), baza ) == Liczba ) else
cout << "paskudny błąd dla liczby: " << licznba << ' ' << baza << endl

@loginus pierwsze dwa punkty rozumiem i przemyślę, ale z trzecim się wstrzymam, gdyż wolałbym nie korzystać z czegoś, czego jeszcze nie rozumiem i nie przerabiałem

@narbej W takim razie przyjrzę się lepiej tej 11 i jak będzie AC to dam znać, dziękuję za rady! :wink:

Z racji, że jestem trochę leniwy, trochę przerobiłem kod, tak, żeby nie musieć ręcznie wpisywać liczb:
pod a podstawiłem zmieniające się i
pod ile podstawiałem coraz większe liczby
Do tego dodałem sobie licznik wersów, bo coś mi się nie zgadzało i okazało się, że dla ile=300 program zaczyna wypisywać od i=4, czy to może być przyczyną błędu?
http://ideone.com/Vr7Zil18
EDIT: Przy ręcznym wypisywaniu wszystko działa jak należy, szukam błędu dalej

Taaaak,
Możesz się naszukać. :wink:
Po:
1. Kod wklejaj do okienka kodu a nie stdin, czyli: http://ideone.com/UtnOhK24
2. Poprawiłeś "tej 11", więc wystrarczyło już bez sprawdzań, wysłać do sprawdzenia na spoja.
3. Teraz, tylko musisz pousuwać to co powstawiałeś z powodu lenistwa - więc wygląda, że twoje lenistwo spowodowało podwojenie pracy. Najpierw wykombinowanie, potem wstawianie dodatkowych linijek + zakomentowanie, a teraz czeka Cię powrócenie do poprawnego kodu.

PS
Te sprawdzanie trzeba było wpisać do twojego pierwszego-błędnego kodu.

Emmmm...zaakceptowało :expressionless:
Dałbym sobie rękę uciąć, że raz już sprawdziłem kod po tej poprawce i nie działało...no nic. Masz u mnie Mercedesa jak już zacznę zarabiać na tym miliony! Dzięki!
Jeśli rozwiązałem, to kody, usuwam, tak?

Teoretycznie tak, ale praktycznie nie mam pojęcia. Tak naprawdę, wątpię czy ktoś [ambitny] to będzie czytał. A kto "jedzie" na ściąganiu, to i tak pewnie będzie szukał i googlował, więc co za różnica, czy znajdzie gdzieś czy tu? Tym bardziej, że w zasadzie wszystkie twoje kody [nawet ostatni] nie są od razu na AC, więc jeżeli ktoś skopjuje bezmyślnie to dostanie WA - wrong answewr.

Więc musisz sam zadecydować, chociaż, bez twoich kodów, to cała dyskusja jest [będzie] taka trochę bez sensu, moim skromnym zdaniem.

PS
to fakt, że z podpowiedziami twoje kody WA == AC, ale każdy chętny, będzie musiał jednak trochę poczytać i pomyśleć.

1 year later

Witam, potrzebowałbym wskazówki - mianowicie, posiadam następujący kod:


chciałbym aby państwo zwrócili uwagę na pętlę for w funkcji KONWERSJA - próbowałem różnych konfiguracji i za każdym razem wyświetla mi śmieci wykraczające poza zakres danych tablicy. Nie mam pojęcia, w którym miejscu popełniam błąd. Dla powyższego kodu wpisując 1263 wyświetla mi wynik 4 E F 4274172, zmieniając konfigurację FOR za każdym razem pojawiają się śmieci. Zgodnie z zasadą działania pętli nie powinno w powyższym przykładzie wyświetlać śmieci na końcu, przynajmniej tak mi się zdaje :slight_smile:

Pozdrawiam

ja otrzymałem

4 E F 0

czyli prawie dobrze :slight_smile: (tylko 16 razy więcej, niż być powinno)

skoro znasz problem, to on jest tylko twój :slight_smile:

linijka 73 byla winna -> usuniecie cout poprawilo wyswietlanie. Dzieki za pomoc :slight_smile:

1 year later

Cześć,
napisałem rozwiązanie zadania, zostało zaakceptowane, i w sumie mógłbym sobie przejść do następnego problemu. Ale spojrzałem na tablice wszystkich i najlepszych zgłoszeń. Mój kod, napisany w C++, kompilowany w C++14 (gcc 8.3), wykonał się w 0.05 sekundy. Not great, not terrible. Ale są co najmniej dwie setki osób, które stworzyły kod wykonujący się w 0.00 sekund. Również w C++. Chciałbym więc spróbować się dowiedzieć co może być elementem, który spowalnia mój program. Jednocześnie nie chcę publikować kodu, który jest gotowym rozwiązaniem. Więc spróbuję swój kod opisać. Jeśli wyjdzie niezrozumiale, a będziecie chcieli mi nadal pomóc, to wtedy się zastanowimy czy mam tu dać cały kod, czy tylko jakąś część.

Cały program korzysta tylko z biblioteki iostream.
Mam jedną stałą globalną: 16-elementowa tablica char z elementami od ‘0’ do ‘F’.
Następnie jest deklaracja funkcji, która przyjmuje dwa argumenty liczbowe: liczbę w systemie dziesiętnym i podstawę systemu, na który ma nastąpić przeliczenie. Pomijam jakiekolwiek sprawdzenie czy wpisane liczby są poprawne - zakładam, że sędzia wie co robi.
Definicja funkcji jest na końcu kodu.
Funkcja zwraca string. String ten jest zadeklarowany na samym początku w ciele funkcji i zainicjalizowany wartością “”.
Następnie jest pętla warunkowa do{}while(), która się będzie wykonywać tak długo, aż liczba wejściowa będzie większa od zera.
Wewnątrz pętli deklaracja zmienne int z od razu podstawioną wartością jako modułem dzielenia liczby wejściowej przez podstawę systemu.
Dalej przeliczenie liczby wejściowej: różnica jej samej i zmiennej z poprzedniej linijki podzielona przez podstawę systemu.
Następnie podstawienie do stringa wyjściowego sumy znaku z odpowiedniego indeksu zmiennej globalnej i poprzedniej wartości stringa.
Po wyjściu z pętli funkcja zwraca aktualną wartość stringa.
W funkcji głównej jest deklaracja zmiennej int oznaczającej liczbę zestawów danych do obliczenia, oraz pobranie liczby z wejścia do tej zmiennej za pomocą cin>>.
Główna pętla programu jest w formie while(){} z dekrementacją zmiennej w warunku.
W pętli: deklaracja zmiennej liczbowej, do której jest wczytywana liczba z wejścia za pomocą cin>>.
Na koniec w jednej linii wywołanie strumienia wyjściowego cout<<, w którym jest wywołanie funkcji przeliczającej najpierw dla 16, później dla 11 - rozdzielone spacją i endl na końcu.
Za pętlą zwyczajowe zwrócenie zera.

Czy już na podstawie takiego opisu, bez samego kodu, da się powiedzieć co spowalnia mój program? Przede wszystkim - czy to kwestia samego algorytmu, czy jednak jakiejś złej praktyki kodowania?

W zasadzie na podstawie pierwszego akapitu, mógłbym już Ci podpowiedzieć, sam tak miałem gdy zgłaszałem swoje pierwsze zadania.

Możesz wyszukać w goglach : “c++ przyśpieszenie i/o” -> i poczytać np: https://4programmers.net/C/Wymuszanie_wysokiej_wydajności_iostream6
Te sposoby mają się nijak do dobrej praktyki kodowania, albo nawet wręcz są złą praktyką, ale coś za coś.
Dalsze przyśpieszenie i dalsze złe praktyki ;-), to zastąpienie cin/cout funkcjami scanf/printf
a następnie jeszcze gorsze praktyki, użycie funkcji z przyrostkiem _unlocked: http://www.algorytm.edu.pl/fast-i-o.html6 <-- to ni jedyna strona, ale zobacz kto jest autorem :wink: : Autor wielu konkursów, a także aktualnie zbliżającego się: Konkurs z okazji Dnia Dziecka

Czy jeszcze coś szybszego? wczytanie całego wejścia od razu w całości do bufora?

Jeszcze jedna zła praktyka - może być nie przenośna i nie działać np na windowsie:

#include <bits/stdc++.h> 
// -- zastępuje wypisywanie większości bibliotek

Czemu są to złe praktyki - to już inna historia, jak dostanę od @nikusek007 tego obiecanego Mercedesa. :wink:

Aby ocenić, czy twój kod jest dobry, czy spełnia standarty dobrej praktryki, ktoś musiałby zobaczyć twój kod. Będzie to jednak zawsze ocena mniej lub więcej subiektywna. Np jeżeli nie musisz, nie używaj zmiennych globalnych. Lub inaczej, jeżeli możesz użyć zmienną globalną lub lokalną, wybieraj lokalną.

Można wczytywać jedną daną, przetwarzać, wypisywać wynik, nie musisz wczytywać całości od razu do tablicy czy innego kontenera.

2 years later

Hej,
Napisałam to zadanie. Lokalnie zwraca poprawne wyniki dla różnych danych, jednak spoj go nie przyjmuje. Mogłabym prosić o jakieś wskazówki dlaczego? Załączam plik z kodem.systemyPozycyjne.txt7 (2.3 KB)

Załącz swój kod jako link do ideone. Wtedy możesz mieć więcej chętnych do pomocy. Mi na przykład nie chce się ściągać Twojego kodu w postaci pliku tekstowego, a jesli byłby podany jako link do ideone to być może… :slight_smile:

public class NumberSystems
Jesli klasa musi byc publiczna to musi miec nazwe “Main” (na jezyku java sie nie znam, wiec popatrzylem na przyklad z ideone dla tego jezyka)

Wyjscie programu laduje w jednej linii??