High School Programming League 2008/2009

Środowisko systemu SPOJ

Nadsyłane programy będą kompilowane i uruchamiane w automatycznym środowisku testowym pracującym w systemie Linux. Programy muszą trzymać się dokładnie zadanej specyfikacji wejścia i wyjścia, w szczególności nie należy wypisywać żadnych dodatkowych komunikatów takich jak "podaj liczbę" itp.

Przykładowe kompilatory
Nadsyłane programy, w zależności od języka programowania zadeklarowanego przez Rozwiązującego, będą kompilowane przez:

  • gcc 4.0.0-8 (wraz z biblioteką standardową) dla języka C.
  • g++ 4.0.0-8 (wraz z biblioteką standardową, w tym Standard Template Library) dla języka C++.
  • fpc 2.0.4 (wraz z biblioteką standardową i rozszerzeniem Delphi dla FreePascal) dla języka Pascal.
  • j2se jdk 5.0 (wraz ze standardową biblioteką klas firmy Sun dla Javy, z wyłączeniem niektórych klas multimedialnych i odpowiedzialnych za interakcję z systemem) dla języka Java. Punktem startowym uruchomienia dla programów pisanych w języku Java jest metoda public static void main (String[] a) klasy Main, która musi zostać zdefiniowana przez Rozwiązującego.
  • inne kompilatory są dostępne w systemie, w zależności od wybranego języka programowania: C 99strict, D, C#, Nemerle, Haskell, O'Caml, Prolog, Scheme, Lips, Clips, Icon, Whitespace, Fortran, Smalltalk, Ada95, Assembler (Nasm), Intercal, Php, Pike, Ruby, Perl, Brainf**k.

Ograniczenie rozmiaru kodu źródłowego
Rozmiar nadsyłanego pliku z kodem źródłowym jest ograniczony do 50 tysięcy bajtów w jednym pliku. Dodatkowe ograniczenia mogą być nakładane w poszczególnych zadaniach. Nie jest dopuszczalne korzystanie z niestandardowych bibliotek lub plików zewnętrznych.

Ograniczenie czasu wykonywania programu
Dopuszczalny czas działania programu jest ograniczony dla każdego zestawu testowego. Ograniczenie jest nie mniejsze niż 1s i dobrane w taki sposób, aby rozwiązanie zestawu było możliwe. Rozwiązania zadań będą sprawdzane na jednakowych komputerach PIII 733 MHZ.

Ograniczenie pamięci
Pamięć dostępna dla programu jest nie mniejsza niż 64MB

Obsługa wejścia i wyjścia
Program powinien obsługiwać standardowe wejście oraz standardowe wyjście. Nie ma potrzeby wczytywania najpierw wszystkich danych wejściowych, a po obliczeniach wypisywania wszystkich wyników. Można przetwarzać dane porcjami: wczytać część danych, dla nich wypisać wyniki i tak dalej. Technicznie odbywa się to przez przekierowanie standardowych strumieni do plików. W ten sam sposób możesz testować swoje programy na swoim domowym komputerze.

Przykład rozwiązania zadania
Zadanie: Napisać program do dodawania dwóch liczb całkowitych. Na wejściu podane są w oddzielnych liniach dwie liczby naturalne A oraz B mniejsze od 100. Na wyjściu należy wypisać ich sumę A + B.


Przykład danych wejściowych:
2
3

Przykład danych wyjściowych:
5

Rozwiązanie w języku C:

#include <stdio.h>
int main()
{
	int a, b;
	scanf("%d %d", &a, &b);
	printf("%d\n",a+b);
	return 0;
}

Rozwiązanie w języku PASCAL:

program ex;
var a, b: integer;
begin
	read(a,b);
	writeln(a+b);
end.

Rozwiązanie w języku Java:

public class Main
{
	public static void main (String[] args) throws java.lang.Exception
	{
		java.io.BufferedReader r = new java.io.BufferedReader
			(new java.io.InputStreamReader (System.in));
		int a=Integer.parseInt(r.readLine()),
		    b=Integer.parseInt(r.readLine());
		System.out.println(a+b);
	}
}

Zgłaszanie rozwiązań

Rozwiązania zadań programistycznych można zgłaszać wyłącznie poprzez stronę http://hs.spoj.pl/. Rozwiązania jednego zadania można nadsyłać wielokrotnie. Liczba punktów przyznanych uczestnikowi za rozwiązanie zadania jest równa liczbie punktów uzyskanych przez jego najlepsze rozwiązanie tego zadania.

Aby zgłosić rozwiązanie zadania, należy...
...wybrać zadanie ze spisu: zadania i kliknąć przycisk 'Zgłaszanie'

Aby obejrzeć własne rozwiązania danego zadania, należy...
...wybrać zadanie ze spisu: zadania i kliknąć na 'Moje zgłoszenia'

Możliwe odpowiedzi systemu na nadesłane rozwiązanie
AC - accepted (zaakceptowano) - program prawidłowo zakończył działanie i zwrócił poprawny wynik (zamiast słowa zaakceptowano system może również wynik opisany liczbą - w takim wypadku jej znaczenie jest opisane w treści zadania.
WA - wrong answer (błędna odpowiedź) - program poprawnie zakończył działanie, zwrócił jednak błędny wynik
TLE - time limit exceeded (przekroczono limit czasu) - kompilacja programu zakończyła się powodzeniem, jednakże program podczas wykonywania przekroczył dopuszczalny limit czasu
CE - compilation error (błąd kompilacji) - program nie może się skompilować, komunikat o błędzie jest dostępny pod linkiem "błąd kompilacji" (uwaga do osób korzystających z języków interpretowanych takich jak Python, Perl i inne: błąd kompilacji może być sygnalizowany jako WA
RE - runtime error (błąd wykonania) - program poprawnie się skompilował, jednak działanie programu zostało przerwane jednym z sygnałów:

- SIGSEGV (signal 11) - "segmentation fault", najczęstszy błąd (przekroczenie dozwolonego obszaru pamięci, etc...);
- SIGXFSZ (signal 25) - "output limit exceeded", przekroczony limit rozmiaru wyjścia;
- SIGFPE (signal 8) - "floating point error", dzielenie przez zero;
- SIGABRT (signal 6) - błąd podczas wykonywania makra assert;
- NZEC (non-zero exit code) - program zwrócił kod błędu, różny od zera (przydatne programistom języków skryptowych);
- inny - inny rodzaj błędu; 

Uwagi techniczne dla programujących w języku C/C++

Uruchamianie rozwiązań na domowym komputerze
Stosując stałą symboliczną ONLINE_JUDGE można odróżnić kod kompilowany na serwerze systemu SPOJ i na komputerze domowym.
Przykład:

#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif

Dane wejściowe będą wówczas pobierane z pliku input.txt, a dane wyjściowe będą zapisywane do pliku output.txt tylko poza środowiskiem SPOJ.

Uwagi techniczne dla programujących w innych systemach operacyjnych

Kodowanie nowej linii w plikach tekstowych
Proszę zwrócić uwagę, że kodowanie końca wiersza w niektórych systemach może się różnić od kodowania w systemie Linux. Może to być przyczyną trudnych do zlokalizowania błędów.

Wykorzystywanie 64-bitowych liczb
Jeżeli Rozwiązujący wykorzystuje kompilator, w którym nie istnieje typ long long, przykładowo pakiet MS VisualC++, to w celu zapewnienia prawidłowej kompilacji z typem __int64 można utworzyć synonim:

#define __int64 long long

Nie należy przy tym zapomnieć o zamianie formatu wejścia (wyjścia) z %I64d na %lld w przypadku korzystania z funkcji typu scanf/printf.

Dalsza lektura

SPOJ System © 2010 Sphere Research Labs. All Rights Reserved.