• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Algorytmy / SPOJ/ olimpiady - tutorial

Object Storage Arubacloud
+15 głosów
1,452 wizyt
pytanie zadane 4 września 2016 w SPOJ przez ZakosiliMiNeta Nałogowiec (30,870 p.)
edycja 5 września 2016 przez ZakosiliMiNeta

Siemanko. Zauważyłem, że na trello jest do zrobienia tutorial na temat SPOJA, algorytmów. To postanowiłem, że zrobię.

Może zacznę do czego służy SPOJ i platformy tego typu. Służą one by rozwijać myślenie oraz jak by pisać optymalny kod, a nie pisanie ładnego kodu. 

Na start radzę wam się zaznajomić z takimi jak pojęciami jak: złożoność obliczeniowa i notacja O. Pokrótce omówię te pojęcia ale i tak radzę poczytać na google o nich. 

Złożoność obliczeniowa - jest to pojęcie jak długo się wykonuje program lub jak dużo pamięci zużywa. Na przykład jeśli mamy program i on wykonuje 2 zagnieżdżone pętle i jeszcze jakąś pętle ( nie jest ona zagnieżdżona ). To złożoność obliczeniowa będzie tych dwóch pętli zagnieżdżonych.

Notacja O - jest to sposób zapisu złożoności obliczeniowej. Biorąc przykład z góry to w przypadku notacji O będzie O ( n^2 ). 

Wiem, że jest to zagmatwane ale dam kilka przykładów ( pseudo kod i zapis w notacji O ) i się może rozjaśni.

int n = 150550;
for ( int i = 0; i < n; i++ ) cout<<i

Tutaj wykonuję jedną pętlę i złożoność wynosi O(n)

int n = 15091421 // te wartości mogą się zmieniać 
int m =  151421413 // te wartości mogą się zmieniać 
for ( int i = 0; i < n; i++)
  for ( int j = 0 j < m; j++) cout<<i+j;

Hmm złożoność to O ( n*m ) bo w każdym obiegu pętli wykonuję drugą pętlę 


cout<<"ala ma psa"

No tu będzie szok złożoność wynosi O ( 1 ).  Wykonuję stałą liczbę operacji ( przy każdym uruchomieniu programu ta liczba operacji się nie zmieni).

int n = 154231431 // może ta wartość się zmienić 
for ( int i = 0; i * i < n; i++)
 for ( int j = 0; j < 15; j++) cout<<i+j;

No tutaj trochę się rozpiszę. Na początku pomyślicie, że złożoność O ( sqrt ( n) * 15 ). Myślicie dobrze ale przyjeło się, że stałą liczbę operacji pomijamy ( druga pętla zawsze będzie wykonywać 15 kroków ). Czyli złożoność wynosi O(sqrt(n)) <- te 15 pomijamy

Dobra główna kwestia skończona. Przejdźmy do kwestii jak się takie zadania pisze, bo jak widzę jak to próbujecie rozwiązać to ręce opadają. 

Kod piszemy jak najprościej. Czyli bez używania klas, wskaźników, tablic dynamicznych takich bajerów <- w przypadku SPOJA i innych konkursów, portali jest to ZŁE. Za to jak piszemy, jak najprościej, tablice deklarujemy poza mainem i na sztywno maksymalną ilość danych ( trochę niejasno ale zaraz podam przykład ). Zamiast pisać swoje struktury danych to upewnijcie się, że nie ma ich w STL. 

Przykład poprawny 

#include <iostream>
using namespace std;
// przykład poprawny do zadania  "tablice" na SPOJ 
int tab[100]; // w zadaniu jest napisane jasno maksymalna ilość danych to 100 liczb 
int t, n; /// liczba testów i liczba danych tablicy
 
void wypisz (int z){
	for ( int i = 0; i < z; i++ ) cout<<tab[i]<<endl;
	// nie używamy żadnych wskaźników do tablicy
}
void podaj ( int z ){
	for ( int i = 0; i < z; i++ ) cin>> tab[i];
}

int main() {
	cin >> n;
	for ( int i = 0; i < n; i++ ){
		cin >> t;
		podaj ( t );
		reverse ( tab, t);
		wypisz(t);
	}
}

Przykład niepoprawny 

#include <iostream>
using namespace std;
// Przykład niepoprawny rozwiązywania zadań 
 
void wypisz (int* tab, int z){
	for ( int i = 0; i < z; i++ ) cout<<tab[i]<<endl;
	// bawimy się jakimiś wskaźnikami i utrudniamy sobie życie bo łatwo można się pomylić 
}
void podaj ( int* tab, int  z ){
	for ( int i = 0; i < z; i++ ) cin>> tab[i];
}

int main() {
	int n;
	cin >> n;
	for ( int i = 0; i < n; i++ ){
		int t;
		cin >> t;
		int *tab = new int [t]
		podaj ( t );
		reverse ( tab, t);
		wypisz(t);
	}
}

Przykłady raczej są do poprawy bo po prostu słabo obrazują o co mi chodzi. 

Jak wypisujemy dane. Istnieją dwie możliwości( online i offline ). Online polega, że po otrzymaniu danych jesteśmy wstanie wypisać wynik np jak w zadaniu tablice, dostajemy tablice, odwracamy i wypisujemy. Wypisywanie Offline polega na zmagazynowaniu wszystkich danych i je wypisaniu po obliczeniu wszystkich testów, czyli w przeciwieństwie do online wczytujemy wszystkie podane tablice i je odwracamy, a następnie wypisuje po kolei. 

Co do wypisywania danych ma być ząb w ząb podany wynik na przykładzie do zadania ( na samym dole zadania są podane testy przykładowe i odpowiedzi do nich ). 

Dobra wysłałem zadanie i dlaczego SPOJ mnie nie lubi ?

Popularne komunikaty z SPOJ 

wrong answer/ zła odpowiedź no tu nasz program podał złą odpowiedź, może się zdarzyć, że źle wypisaliście dane. 

compilation error / błąd kompilacji - co tu dużo mówić, program się na sprawdzaczce nie skompilował i dał error.

time limit exceeded / przekroczono limit czasu- tutaj jest trochę ciekawe. Bo wasz program jest za wolny czyli program nie jest zoptymalizowany ( da się lepiej rozwiązać) .

Tutaj nie jestem pewien czy takie błędy wyskakują na SPOJU, ale na pewno wyskakują w szanujących się sprawdzaczkach

naruszenie bezpieczeństwa  - wykonujemy takie operacje które pytają system o czas lub coś podobnego. Może się to zdarzyć gdy naruszymy limit pamięci przeznaczony na program lub wyjechaliśmy poza zakres tablicy. 

Chyba wszystkie sprawdzaczki mogą nie wypisać żadnego błędu z wyżej wymienionych, a napiszą np error501. Takie błędy trzeba już wygooglać i przeczytać o co chodzi bo są to bardzo specyficzne błędy.

Chyba wszystkie potrzebne rzeczy na start przekazałem. Błędy na pewno są to proszę pisać i będę poprawiał. Uwagi, pytania z chęcią odpowiem. Jeśli na coś wpadnę to dopiszę 

3
komentarz 5 września 2016 przez manjaro Nałogowiec (37,390 p.)

Błędy na pewno są to proszę pisać i będę poprawiał.

"po za" -> poza

"nie poprawny" -> niepoprawny

"nie jasno" -> niejasno 

 

komentarz 5 września 2016 przez ZakosiliMiNeta Nałogowiec (30,870 p.)
edycja 5 września 2016 przez ZakosiliMiNeta
Dziękuję. Jutro poprawię. Bo teraz nie mogę

@edit

Poprawione

1 odpowiedź

+1 głos
odpowiedź 5 września 2016 przez Paweł Głomski Obywatel (1,650 p.)

"w zadaniu pisze jasno" -> jest napisane ;>

komentarz 5 września 2016 przez jpacanowski VIP (101,940 p.)
To uwagi do wszystkich tutaj wypowiadających się. Serio, ja już nie wiem kto co pisał :D
komentarz 5 września 2016 przez manjaro Nałogowiec (37,390 p.)
Przepraszam że to ja w sumie zacząłem ten temat ortografii. Kolega napisał mały poradnik, który na pewno komuś się przyda. I super dostałby 5 z informatyki. Ale w tym samym momencie dostałby pałę z języka polskiego. Wiem, to nie jest poradnik jak pisać poprawnie w języku polskim, ale pewien poziom trzeba trzymać. Tego się wymaga od każdego maturzysty. Widzieliście kiedykolwiek błąd ortograficzny w poradnikach Mirka Zelenta?

I żeby nie było, nie czepiam się kolegi @zakosili ale fajnie byłoby aby poradnik był kompletny i w miarę bezbłędny.

A prywatnie to nigdy nie mogłem pojąć jak ktoś znający doskonale jakąś dziedzinę może być poniżej średniej w innych dziedzinach. Ale to moje prywatne odczucie.
komentarz 5 września 2016 przez ZakosiliMiNeta Nałogowiec (30,870 p.)

Przepraszam że to ja w sumie zacząłem ten temat ortografii.

Oj dobrze zrobiłeś. Z resztą sam prosiłem by wytykać błędy :)

kolega napisał mały poradnik,

Mogę go rozszerzyć tylko musicie mi podpowiedzieć jakie zagadnienie / zagadnienia rozszerzyć, napisać. Co do przykładów do takiego poradnika to bym musiał już kogoś kto zna dobrze C++ poprosić by napisał nie poprawne przykłady. Bo znam go jedynie właśnie do takich jak SPOJ itp.

komentarz 5 września 2016 przez CzikaCarry Szeryf (75,340 p.)
Pisałeś o notacji 'O', no to może teraz kolej na asymptotyczne tempo wzrostu? :)
komentarz 5 września 2016 przez Paweł Głomski Obywatel (1,650 p.)
Nie żeby mi to jakoś przeszkadzało, ale radzę pisać osobne odpowiedzi dot. rozwoju tego "poradnika", żeby nikt nie musiał się później przebijać przez wcześniejsze odpowiedzi nie mające nic wspólnego z tym tematem, .

Podobne pytania

0 głosów
2 odpowiedzi 1,257 wizyt
0 głosów
0 odpowiedzi 468 wizyt
+1 głos
2 odpowiedzi 188 wizyt

92,572 zapytań

141,422 odpowiedzi

319,645 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...