This shows you the differences between two versions of the page.
programare-cc:laboratoare:09 [2020/11/27 23:46] viorel.mocanu |
programare-cc:laboratoare:09 [2021/12/09 13:06] (current) viorel.mocanu [Problema 4] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Breviar 09 - Structuri-Enumerări-Uniuni ===== | + | ===== Laborator 09 - Structuri-Enumerări-Uniuni ===== |
==== Problema 1 (rezolvată) ==== | ==== Problema 1 (rezolvată) ==== | ||
Line 57: | Line 57: | ||
- | |||
- | Programul C care implementează algoritmul descris mai sus va fi: | ||
==== Problema 2 ==== | ==== Problema 2 ==== | ||
---- | ---- | ||
- | Scrieţi o funcţie care să verifice dacă un număr întreg **n** conţine cifra **c**. Numerele **n** şi **c** sunt | + | Moduri în care timpul poate fi exprimat într-un program C: |
- | date ca parametri. Antetul funcţiei trebuie să respecte următorul format: | + | |
- | <code c> | + | * Printr-un întreg lung (tip de date time_t, echivalent cu long int), ce reprezintă numărul de secunde față de ora 0 din 1 ianuarie 1970. |
- | int cifra(int n, int c) | + | * Printr-o structură cu numele tm ce conține: |
- | </code> | + | |
- | + | ||
- | == Date de intrare == | + | |
- | ---- | + | |
- | + | ||
- | Programul primeste 2 parametri **n** si **c** ca in antetul de mai sus | + | |
- | + | ||
- | == Date de ieşire == | + | |
- | ---- | + | |
- | Se va afisa //DA// sau //NU//. Astfel ca //DA// semnifica existenta cifrei **c** in numarul **n**, sau //NU// in | + | |
- | caz contrar | + | |
- | + | ||
- | + | ||
- | == Restrictii si Precizari == | + | |
- | ---- | + | |
- | + | ||
- | * −2,147,483,648 < n < 2,147,483,647 | + | |
- | * 0 ≤ c ≤ 9 | + | |
- | + | ||
- | == Exemplu == | + | |
- | + | ||
- | ---- | + | |
- | ^ Intrare ^ Ieşire ^ | + | |
- | | 13584 3 | DA | | + | |
- | | 100111 0 | DA | | + | |
- | | 666013 8| NU| | + | |
- | + | ||
- | ==== Problema 3 ==== | + | |
- | + | ||
- | ---- | + | |
- | //**Ipoteza lui Goldbach**//: Orice număr par se poate exprima printr-o sumă de două numere | ||
- | prime, nu neapărat distincte. | ||
- | **A**. Scrieţi o funcţie care să verifice dacă un număr întreg este prim sau nu. Funcţia va returna | ||
- | valoarea 1 dacă **N** este număr prim şi 0 în caz contrar. Si **trebuie** sa aiba urmatorul antet: | ||
<code c> | <code c> | ||
- | int prim(int n) | + | struct tm { // definita in time.h |
+ | int tm_sec,tm_min, tm_hour; // sec (0-59), min (0-59), ora (0-23) | ||
+ | int tm_mday, tm_mon, tm_year; // zi (0-31), luna (0-11), an (dupa 1900) | ||
+ | int tm_wday; // ziua din saptamana (0-6) | ||
+ | int tm_yday; // ziua din an (0-365) | ||
+ | int tm_isdst; // +1 Daylight Savings Time, 0 No DST, -1 don't know | ||
+ | }; | ||
</code> | </code> | ||
- | **B**. Scrieţi un program care verifică //**ipoteza lui Goldbach**// prin afişarea tuturor | + | Pentru a facilita lucrul cu date ce reprezintă timpul sunt declarate în biblioteca time.h mai multe funcții. Câteva funcții din time.h: |
- | descompunerilor distincte(de ex. nu se vor afişa şi "5+7" şi "7+5") posibile în sumă de | + | |
- | numere prime ale unui număr citit de la tastatură. Programul va apela funcţia prim. | + | |
- | <note important>Observaţie: Se va considera pentru această problemă că numărul 1 este prim.</note> | + | |
- | == Date de intrare == | + | * time_t time(time_t*) returnează ora curentă (ca număr de secunde); această valoare se pune și la adresa trimisă ca parametru (excepție când se apelează time(NULL) - atunci se va întoarce timpul doar ca rezultat al funcției) |
+ | * struct tm* localtime(const time_t*) transformă o dată din format time_t în struct tm; funcția întoarce un pointer la o structură de tip tm | ||
+ | * char* asctime(const struct tm*) transformă din struct tm într-un șir de caractere ce va reprezenta data în format human-readable | ||
+ | * char* ctime(const time_t*) transformă din time_t într-un șir de caractere ce va reprezenta data în format human-readable | ||
- | ---- | + | Să se scrie un program pentru afișarea orei și datei folosind funcțiile din time.h descrise mai sus. |
- | Un numar **N** par. | ||
- | + | ==== Problema 3 ==== | |
- | == Date de ieşire == | + | |
---- | ---- | ||
- | Afisarea tuturor descompunerilor pentru numarul dat **N** | + | Să se scrie și să se verifice o funcție pentru transformarea orei din struct tm în șir de caractere (se vor afișa oră, minut, secundă) : |
- | == Restrictii == | + | char* timestr(struct tm t, char* time); |
- | ---- | + | Rezultatul funcției este același cu al doilea argument și reprezintă adresa unde se depune șirul de caractere rezultat. |
- | + | ||
- | * 2 ≤ N ≤ 200000 | + | |
- | + | ||
- | == Exemplu == | + | |
- | + | ||
- | + | ||
- | ---- | + | |
- | + | ||
- | ^ Intrare ^ Ieşire ^ | + | |
- | | 12 | 1 + 11 \\ 5 + 7 | | + | |
Line 144: | Line 101: | ||
---- | ---- | ||
- | Se citesc de la tastatură patru numere întregi reprezentând două fracţii //x1 / y1// şi //x2/ y2//. | + | Să se definească o structură pentru un vector struct vector de întregi alocat dinamic care conține: |
- | Aduceţi fracţiile la acelaşi numitor (cel mai mic posibil) folosind o funcţie care calculează cel | + | |
- | mai mic multiplu comun a două numere întregi. Consideraţi că fracţiile date ca input sunt | + | |
- | deja în formă ireductibilă. Antetul funcţiei trebuie să respecte următorul format: | + | |
- | <code c> | + | * int* v - adresa vector |
- | int cmmmc(int a, int b) | + | * int cap - dimensiune alocata (maxima) |
- | </code> | + | * int n - dimensiune efectiva (număr de întregi stocați) |
- | <note tip>Hint: cmmmc(a, b) = (a * b) / cmmdc(a, b);</note> | + | Să se scrie funcții pentru: |
- | == Date de intrare == | + | * inițializarea unui vector (cu o alocare initiala de memorie): void init_vector(vector *a, int nr) |
- | ---- | + | * adăugarea unui nou element la vector (cu o eventuală realocare a vectorului): void adauga_vector(vector *a, int n) |
+ | * afișarea unui vector: void scrie_vector(vector a) | ||
- | Patru numere intregi reprezentand **x1**, **y1**, **x2**, **y2** cu semnificatia din enunt | ||
- | == Date de ieşire == | + | Testaţi programul adăugând pe rând, şi afişând vectorul după fiecare adăugare, numerele de la 0 la 100. |
- | ---- | + | |
- | Cele 2 fractii aduse la acelasi numitor | ||
- | |||
- | |||
- | == Restrictii == | ||
- | ---- | ||
- | |||
- | * y1 != 0 | ||
- | * y2 != 0 | ||
- | |||
- | == Exemplu == | ||
- | ---- | ||
- | |||
- | ^ Intrare ^ Ieşire ^ | ||
- | | 1 2 \\ 1 11 | 11 22 \\ 2 22 | | ||
- | | 5 12 \\ 3 14 | 35 84 \\ 18 84 | | ||
==== Problema 5 ==== | ==== Problema 5 ==== | ||
---- | ---- | ||
- | Să se scrie un program pentru calculul sumei seriei Taylor pentru funcţia //e^x// până la un | + | Să se definească o structură pentru un număr complex cu componente reale (de tip float) şi funcţii pentru operatorii aritmetici cu numere complexe: |
- | termen dat: | + | |
- | //e^x = 1 + x/1! + (x^2)/2! + (x^3)/3! + ... + (x^n)/n!// | ||
- | Se vor defini şi utiliza următoarele funcţii: | + | * adunarea: complex adunare(complex a, complex b) |
- | * Funcţie pentru calculul sumei seriei Taylor în punctul x până la un termen n dat: <code c> double taylor(double x, int n) </code> | + | * scăderea: complex scadere(complex a, complex b) |
- | * Funcţie pentru calculul factorialului unui număr întreg: <code c> int factorial(int n) </code> | + | * înmulţirea: complex inmultire(complex a, complex b) |
- | * Funcţie pentru calculul puterii întregi a unui număr dat: <code c> double putere(double x, int n) </code> | + | * ridicarea la o puterea întreagă: complex putere(complex a, int putere) |
+ | * afişarea sub forma (re,im): void scrie(complex a) | ||
- | == Date de intrare == | ||
- | ---- | ||
- | Fişierul de intrare va avea o singură linie, pe care se vor afla un număr real **X** şi un număr | + | Folosind funcţiile anterioare, să se scrie un program pentru calulul valorii unui polinom de variabilă complexă cu coeficienţi reali. |
- | natural **N**. | + | |
- | == Date de ieşire == | ||
- | ---- | ||
- | |||
- | Valoarea expresiei expuse mai sus pentru **x** şi **n** date, cu precizie de patru zecimale. | ||
- | |||
- | == Restrictii == | ||
- | |||
- | * 0 < N ≤ 1000 | ||
- | |||
- | == Exemplu == | ||
- | |||
- | ^ Intrare ^ Ieşire ^ | ||
- | | 2.5 10 | 12.1817 | | ||
==== Problema 6 ==== | ==== Problema 6 ==== | ||
---- | ---- | ||
- | Se citesc **n** puncte de la tastatură, date prin coordonatele lor: //x[i], y[i], i=1,n//. Să se afişeze | + | Să se scrie un program pentru citirea unor cuvinte și afișarea numărului de apariții al fiecărui cuvânt. |
- | perechea de puncte între care distanţa este maximă (dacă există mai multe astfel de perechi, | + | |
- | se poate afişa oricare dintre ele), precum şi această distanţă. Se va defini şi folosi o funcţie | + | |
- | pentru calculul distanţei dintre două puncte în plan, care trebuie să respecte următorul antet: | + | |
- | <code c> | + | Problema se va rezolva în două variante diferite: |
- | float dist(int x1, int y1, int x2, int y2) | + | |
- | </code> | + | |
+ | * Se va folosi un vector de char* pentru cuvinte (char **) și un vector de numere întregi. Cei doi vectori se alocă și extind dinamic (se realocă dacă este nevoie). | ||
+ | * Se va defini o structură Pereche ce conține un cuvânt și numărul lui de apariții și un vector de astfel de perechi. Vectorul se alocă și se extinde dinamic. | ||
- | == Date de intrare == | ||
- | ---- | ||
- | Un numar natural **n**, urmate de **n** linii, pe fiecare linie cate un punct dat prin coordonatele sale | ||
- | în plan, cu specificatia din enunt. | ||
- | |||
- | == Date de ieşire == | ||
- | ---- | ||
- | |||
- | Pe primele doua linii perechea de puncte intre care distanta e maxima. Pe a treia linie se va | ||
- | regasi distanta | ||
== Exemplu == | == Exemplu == | ||
Line 241: | Line 149: | ||
^ Intrare ^ Ieşire ^ | ^ Intrare ^ Ieşire ^ | ||
- | | 4 \\ 0 0 \\ 0 1 \\ 1 0 \\ 1 1 | 0 0 \\ 1 1 \\ 1.414214 | | + | |6 \\ unu doi \\ trei doi trei trei | unu 1 \\ doi 2 \\ trei 3| |
- | + | ||
- | ==== Problema 7 ==== | + | |
- | ---- | + | |
- | + | ||
- | Scrieţi o funcţie care sortează cifrele unui număr astfel: | + | |
- | * descrescător, dacă numărul conţine cifra 0 | + | |
- | * crescător, dacă numărul nu conţine cifra 0 | + | |
- | + | ||
- | Funcţia trebuie să respecte următorul antet: | + | |
- | <code c> | + | |
- | int transforma(int n) | + | |
- | </code> | + | |
- | + | ||
- | <note tip>HINT! Pentru a sorta cifrele, cea mai simpla metoda este sa folositi un vector cu 10 elemente | + | |
- | in care sa memorati pentru fiecare cifra, de cate ori apare aceasta in numar. Pentru a afisa | + | |
- | numarul sortat, trebuie sa parcurgeti vectorul si sa afisati cifrele in ordine crescatoare/des | + | |
- | </note> | + | |
- | + | ||
- | + | ||
- | == Date de intrare == | + | |
- | ---- | + | |
- | + | ||
- | Un numar dat **N** cu specificatia din enunt. | + | |
- | + | ||
- | == Date de ieşire == | + | |
- | ---- | + | |
- | + | ||
- | Cifrele numarului dat, sortate dupa cum se cere in enunt. | + | |
- | + | ||
- | + | ||
- | == Restrictii == | + | |
- | ---- | + | |
- | + | ||
- | * 0 ≤ N ≤ 1000000000 | + | |
- | + | ||
- | == Exemplu == | + | |
- | ---- | + | |
- | + | ||
- | ^ Intrare ^ Ieşire ^ | + | |
- | | 19430123 | 94332110| | + | |
- | | 2534562| 2234556 | | + | |
- | + | ||
- | ==== Problema 8 ==== | + | |
- | ---- | + | |
- | + | ||
- | Scrieţi o funcţie care caculează aria intersecţiei a două dreptunghiuri, date prin coordonatele | + | |
- | colţurilor stânga-sus şi dreapta-jos. Coordonatele sunt numere întregi pozitive. Funcţia | + | |
- | trebuie să respecte următorul antet: | + | |
- | + | ||
- | <code c> | + | |
- | int arie_intersectie(int x11, int y11, int x12, int y12, int x21, inty21, int x22, int y22) | + | |
- | </code> | + | |
- | + | ||
- | == Date de intrare == | + | |
- | ---- | + | |
- | + | ||
- | Se vor citi 8 numere intregi, reprezentand coordonatele colturilor celor 2 figuri geometrice. | + | |
- | Ele vor fi date in ordine conform cu antetul functiei pus la dispozitie in enunt. | + | |
- | + | ||
- | == Date de ieşire == | + | |
- | ---- | + | |
- | + | ||
- | Un numar reprezentand aria intersectiei dintre cele 2 dreptunghiuri. | + | |
- | + | ||
- | + | ||
- | == Restrictii == | + | |
- | ---- | + | |
- | + | ||
- | * Coordonatele sunt numere intregi strict pozitive | + | |
- | * Numerele vor fi in intervalul [0, 1.000.000] | + | |
- | + | ||
- | == Exemplu == | + | |
- | ---- | + | |
- | + | ||
- | ^ Intrare ^ Ieşire ^ | + | |
- | | 1 10 5 5 \\ 2 7 4 4| 4| | + | |
- | | 1 3 3 1 \\ 2 4 4 4 | 0 | | + | |
- | + | ||
- | + | ||
- | + | ||