Elevii care vor participa la Olimpiada Judeean/Naional de Informatic trebuie s aib n vedere urmtoarele:
A) Pentru evitarea erorilor la compilare, codul surselor trebuie s respecte Standarul C++, respectiv Standardul Free Pascal (cu alte cuvinte, s fie corect din punct de vedere al limbajului)
B) Faptul c vitezele de citire/scriere a datelor pot s difere de la o distribuie GNU C la alta.
C) Faptul c exist reguli de formatare a fiierelor de test la concursurile de algoritmic.
A) Respectarea standardului limbajului.
Codul scris n conformitate cu standardul limbajului este un cod portabil i va fi compilat fr erori cu oricare compilator GNU C. Ne vom referi n special la limbajele C/C++, deoarece n cazul acestora apar cele mai multe situaii de practic defectuoas.
1. Nu salvai soluiile cu extensia .c, dect dac suntei siguri c NU dorii s utilizai biblioteca C++. Fiierele cu extensia .cpp vor fi compilate conform standardului C++ (ISO C++ 98), iar cele cu extensia .c vor fi compilate conform standardului C (ISO C 99). n exemplu, sursa.c nu va compila, n timp ce sursa.cpp compileaz:
sursa.c sursa.cpp // Se foloseste biblioteca C #include <stdio.h> // OK
// NU puteti folosi Biblioteca C++ !! #include <fstream.h> // Eroare
struct A { }; A x; // Eroare (standardul C)
int main() { // variabila locala i in for for (int i = 0; i < 10; ++i) //Eroare printf("%d", i);
return 0; } // Se foloseste biblioteca C #include <stdio.h> // OK
// Se foloseste Biblioteca C++ #include <fstream.h> // OK
struct A { }; A x; // OK (standardul C++)
int main() { // variabila locala i in for for (int i = 0; i < 10; ++i) // OK printf("%d", i);
return 0; }
2. Header-e
IMPORTANT! n limbajul C++, heder-ele cu extensia .h nu mai pot fi folosite, dect pentru header-e motenite din limbajul C. Compilatoarele utilizate la OJI/ONI 2014 nu suport stilul vechi de declarare
Observaie: Pentru headerele motenite din C, standardul C++ accept (deocamdat) declarri cu extensia .h : <stdio.h>, <math.h>, <string.h>, etc.
B). Vitezele operaiilor de intrare-ieire n limbajele C/C++
Pentru o distribuie GNU C dat, operaiile de citire/scriere C i C++ difer uneori n ce privete viteza de executare. Funciile scanf(), printf() de pild, sunt pentru anumite distribuii, mai rapide dect operaiile de inserie (<<) sau extracie (>>) din stream-uri, n timp ce pentru alte distribuii lucrurile stau exact invers !
Concurenii sunt sftuii s studieze mediile de lucru pentru OJI/ONI i s aleag acele metode de citire/scriere pe care le consider optime.
1. OJI 2014. Compilatorul mediului Code::Blocks 10.05 are particularitatea c produce executabile pentru care vitezele de citire-scriere cu fiiere sunt mai rapide dect operaiile similare cu stream-uri.
2. ONI 2014 Pentru mediile instalate la ONI 2014, (Ubuntu 12.04: gcc 4.6.3, Windows 7: gcc 4.4.1), s-au facut teste de vitez, aa cum se poate vedea n tabelul de mai jos:
S-a rulat fiecare caz de zece ori i s-a luat media. Compilare: gcc/g++ numfis.cpp
Concluzie:
n Linux e mai rapid citirea i scrierea cu ajutorul stream-urilor n Windows scrierea are loc cu viteze aproximativ egale, ns citirea este mai rapid cu ajutorul funciilor C.
IMPORTANT! NU folosii endl . Utilizai '\n'.
La scrierea n streamuri, datele de ieire se acumuleaz ntr-un buffer (stream) care se golete periodic, nefiind nevoie de accesarea discului la fiecare operaie de scriere. Manipulatorul de format endl, face flush stream-ului de ieire, ceea ce foreaz scrierea pe disc. Dac aceasta se ntampl ntr-un ciclu, atunci viteza scade catastrofal:
Ubuntu 8.04, gcc 4.2.4, AMD Athlon(TM) XP 2500+
#include <fstream> using namespace std;
int main() { ofstream fout("numere.in"); int n = 10000000; for (int i = 0; i < n; ++ i) fout << 7 << '\n'; fout.close(); } #include <fstream> using namespace std;
int main() { ofstream fout("numere.in"); int n = 10000000; for (int i = 0; i < n; ++ i) fout << 7 << endl; fout.close(); } Timp de executare: 3,21 secunde Timp de executare: 40.5 secunde !!!!
C) Formatul fiierelor
1. La OJI i ONI, ca de altfel la toate competiiile de algoritmic naionale sau internaionale, este o practic curent aceea ca ultima linie din fiierele de test de intrare, ct i din cele de ieire, s se termine cu caracterul newline. Concurenii trebuie s in seama de acest lucru.
2. Salvai sursele doar cu numele i extensiile enumerate n enunul problemelor.
3. Respectai formatul fiierului de de ieire! De exemplu, fie o problem care are dou cerine: a) i b). S presupunem c se cere ca rspunsul pentru cerina a) trebuie se gseasc pe linia 1, iar rspunsul pentru cerina b) s se gseasc pe linia 2. n situaia n care nu ai reuit s rezolvai cerina a) dar avei un rspuns pentru b), vei scrie rspunsul pentru cerina b) pe linia 2 i nu pe prima linie !
4. FOARTE IMPORTANT! La OJI ediia 2014, problemele pot avea una sau mai multe cerine. Pentru unele probleme, comisia poate decide ca prima cerin s fie evaluat separat de celelalte, pentru ca un TLE (Time Limit Exceeded) la a doua cerin, s nu afecteze punctajul pentru prima cerin.
Model de enun:
Problema 1 - numere 100 puncte
Se dau dou numere naturale a i b.
Cerin S se determine : 1. Numrul de divizori ai lui a. 2. Toate numerele prime care sunt cuprinse n intervalul [1, b].
Date de intrare Fiierul de intrare numere.in conine pe prima linie un numr natural p. Pentru toate testele de intrare, numrul p poate avea doar valoarea 1 sau valoarea 2. Pe linia a doua a fiierului numere.in se gsesc dou numere naturale a i b, separate printr-un singur spaiu.
Date de ieire Dac valoarea lui p este 1, se va rezolva numai punctul 1. din cerin. n acest caz, n fiierul de ieire numere.out se va scrie un singur numr natural n, reprezentnd numrul de divizori ai lui a. Dac valoarea lui p este 2, se va rezolva numai punctul 2. din cerin. n acest caz, fiierul de ieire numere.out va conine pe linii diferite, toate numerele prime din intervalul [1, b]. Numerele vor fi scrise cte unul pe linie, n ordine crescatoare.
Restricii i precizri
D) 1 a, b 1000 E) Pentru rezolvarea corect a primei cerine se acord 20 de puncte, iar pentru cerina a doua se acord 80 de puncte. F) Pentru primele 50% din testele care verific cerina 2, a, b 100
Exemple numere.in numere.out Explicaie 1 4 5
3
p = 1, a = 4 Atenie! Pentru acest test se rezolv doar cerina 1. Divizori lui 4 sunt: 1,2,4
Se observ c n acest caz valoarea b = 5 nu se utilizeaz.
numere.in numere.out Explicaie 2 3 8
2 3 5 7 p = 2, b = 8 Atenie! Pentru acest test se rezolv doar cerina 2. Numerele prime din intervalul [1, 8] sunt 2, 3, 5, i 7
Timp maxim de execuie: 1 secund/test. Memorie total disponibil 4 MB, din care 2 MB pentru stiv Dimensiunea maxim a sursei: 5 KB.