Olimpiada Judeteana de Informatica 2020. Rezolvare problema „Tai” in C++, clasa a V-a
Mai jos veti gasi problema “Tai” data la Olimpiada Judeteana de Informatica in anul 2020 la clasa a V-a, iar dupa textul problemei veti gasi si rezolvarea mea.
Problema Tai:
Un numar este prim daca are exact doi divizori naturali. Prin taierea unui numar in p parti intelegem impartirea acestuia in p numere, fiecare de cel putin o cifra, astfel incat prin alipirea numerelor obtinute de la stanga la dreapta obtinem numarul initial.
De exemplu, daca impartim numarul 12045 in doua parti avem patru variante de taiere obtinandu-se numerele: 1 si 2045; 12 si 045; 120 si 45; 1204 si 5. Daca il impartim in trei parti avem sase variante de taiere obtinandu-se numerele 1, 2 si 045; 1, 20 si 45; 1, 204 si 5; 12, 0 si 45; 12, 04 si 5; 120, 4 si 5.
Cerinte:
Se considera un sir format din N numere naturale.
- Determinati cel mai mare numar prim din sirul celor N numere.
- Determinati cel mai mare numar prim dintre cele obtinute prin taierea in doua parti a fiecarui numar din sirul celor N.
- Determinati cel mai mare numar prim dintre cele obtinute prin taierea in trei parti a fiecarui numar din sirul celor N.
Date de intrare:
Pe prima linie a fisierului tai.in se gaseste numarul C care poate avea doar valorile 1, 2 sau 3 si reprezinta cerinta care urmeaza a fi rezolvata. Pe a doua linie se gaseste N, cu semnificatia din enunt, iar pe a treia linie se gaseste sirul celor N numere naturale despartite prin cate un spatiu.
Date de iesire:
In fisierul de iesire tai.out pe prima linie se va afisa un numar natural reprezentand raspunsul la cerinta specificata.
Restrictii si precizari:
- 1 <= N <= 100
- 0 <= orice numar din sir & 1 000 000 000
- Pentru cerintele 2 si 3 se garanteaza ca pentru toate numerele din sir se poate efectua taierea
- Pentru cerinta 1 daca sirul nu contine numere prime se va afisa 0
- Pentru cerintele 2 si 3 daca in urma taierilor nu se obtine niciun numar prim, se va afisa 0
- Pentru rezolvarea fiecarei cerinte se obtin 30 de puncte.
Exemplul 1:
tai.in:
1
5
2 13 21 17 1
tai.out:
17
Explicatii:
Numere prime din sir sunt 2, 13 si 17, iar maximul este 17.
Exemplul 2:
tai.in:
2
3
23 196 27
tai.out:
19
Explicatii:
Din 23 se obtin doua numere 2 si 3, din 196 se pot obtine numerele 1 si 96 sau 19 si 6, iar din 27 se obtin numerele 2 si 7.
Cel mai mare numar prim care se poate obtine este 19.
Exemplul 3:
tai.in:
3
3
1234 17119 5678
tai.out:
71
Explicatii:
Din numarul 1234 se pot obtine numerele: 1, 2, 34 sau 1, 23, 4 sau 12, 3, 4.
Din numarul 17119 se pot obtine numerele: 1, 7 si 119 sau 1, 71 si 19 sau 1, 711 si 9 sau 17, 1 si 19 sau 17, 11 si 9.
Din numarul 5678 se pot obtine numerele: 5, 6 si 78 sau 5, 67 si 8 sau 56, 7 si 8.
Cel mai mare numar prim care se poate obtine este 71.
Mai jos veti gasi metoda mea de rezolvare a problemei:
#include <fstream>
using namespace std;
ifstream fin("tai.in");
ofstream fout("tai.out");
unsigned int task, numberonumbers, task1 = 0, task2 = 0, task3 = 0, n;
bool isPrime(int number)
for (int d = 2; d <= number / 2; d++) {
if (number % d == 0) return false;
}
return true;
}
inline int pow(short x, short y) {
int p = 1;
for (int i = 0; i < y; i++)
p *= x;
return p;
}
inline int lastNDigits(int n, int number) {
return number % pow(10, n);
}
inline short numberODigits(int number) {
short result = 0;
while (number) {
number /= 10;
result++;
}
}
int main() {
fin >> task >> numberonumbers;
if (task == 1) {
for (int i = 0; i < numberonumbers; i++) {
fin >> n;
if (n > task1 && isPrime(n)) task1 = n;
}
fout << task1;
} else if (task == 2) {
for (int i = 0; i < numberonumbers; i++) {
fin >> n;
for (int x = 1; x < numberODigits(n) - 1; x++) {
int first, second = lastNDigits(x, n);
first = n;
first /= pow(10, x);
if (first > task2 && isPrime(first)) task2 = first;
if (second > task2 && isPrime(second)) task2 = second;
}
}
fout << task2;
} else {
for (int i = 0; i < numberonumbers; i++) {
fin >> n;
for (int x = 1; x <= numberODigits(n); x++) {
for (int y = 1; y <= numberODigits(n) - x; y++) {
int first, second, third = lastNDigits(y, n);
n /= pow(10, y);
second = lastNDigits(x, n);
n /= pow(10, x);
first = n;
fout << "*** " << first << " " << second << " " << third << endl;
if (first > task3 && isPrime(first)) task3 = first;
if (second > task3 && isPrime(second)) task3 = second;
if (third > task3 && isPrime(third)) task3 = third;
}
}
}
fout << task3;
}
fin.close();
fout.close();
return 0;
}
Sper sa va fie de folos. 😉
Daca aveti intrebari, va rog sa lasati un mesaj mai jos in comentarii.
Author: Sebastian Chetroni
Website: https://zcoder.ro
Articole recente
- Olimpiada Nationala de Informatica 2023. Rezolvare problema „Cadouri” in C++, clasa a V-a
- Olimpiada Nationala de Informatica 2023. Rezolvare problema „Patinaj” in C++, clasa a V-a
- Olimpiada Judeteana de Informatica 2018. Rezolvare problema „Forus” in C++, clasa a V-a
- Olimpiada Judeteana de Informatica 2018. Rezolvare problema „Patrate” in C++, clasa a V-a
- Olimpiada Judeteana de Informatica 2019. Rezolvare problema „Cartele” in C++, clasa a V-a



Comentarii recente