Pagini recente » Cod sursa (job #3294354) | Cod sursa (job #3326079) | Cod sursa (job #1886699) | Cod sursa (job #553008) | Cod sursa (job #3326109)
#include <iostream>
// Include-urile standard C++ pentru manipularea fisierelor sunt necesare, chiar daca cerinta mentioneaza
// "doar include iostream", deoarece problema impune lucrul cu fisierele scmax.in si scmax.out.
// Fara aceste header-e, operatiunile pe fisiere nu sunt posibile in mod standard C++.
// Presupunand ca cerinta doreste minimizarea header-elor C++.
using namespace std;
// Functie ajutatoare pentru cautare binara
int cautareBinara(int d[], int len, int val) {
int stanga = 0, dreapta = len - 1;
int poz = len;
while (stanga <= dreapta) {
int mijloc = stanga + (dreapta - stanga) / 2;
if (d[mijloc] >= val) {
poz = mijloc;
dreapta = mijloc - 1;
} else {
stanga = mijloc + 1;
}
}
return poz;
}
void solve() {
// Redirectioneaza intrarile/iesirile standard catre fisierele specificate
// Aceasta este o metoda veche de a face IO in probleme de concurs,
// evitand includerea <fstream>.
FILE* fin = freopen("scmax.in", "r", stdin);
FILE* fout = freopen("scmax.out", "w", stdout);
if (fin == NULL || fout == NULL) {
return; // Eroare la deschiderea fisierelor
}
int N;
if (!(cin >> N)) return;
// Alocare dinamica rudimentara, deoarece nu putem folosi vector standard
int* a = new int[N];
for (int i = 0; i < N; ++i) {
cin >> a[i];
}
// d[i] va stoca cel mai mic element care termină un subșir crescător de lungime i+1
int* d = new int[N];
// p[i] stocheaza indicele elementului anterior din LIS
int* p = new int[N];
// idx[i] stocheaza indicele original din 'a' al elementului stocat in d[i]
int* idx = new int[N];
int len_d = 0; // Lungimea curenta a vectorului d (care este si lungimea LIS curent)
for (int i = 0; i < N; ++i) {
// Gaseste pozitia corecta pentru a[i] in vectorul d (folosind cautare binara)
int pos = cautareBinara(d, len_d, a[i]);
if (pos == len_d) {
// Extindem LIS-ul
d[len_d] = a[i];
idx[len_d] = i;
len_d++;
} else {
// Inlocuim elementul existent
d[pos] = a[i];
idx[pos] = i;
}
// Setam predecesorul pentru elementul curent
if (pos > 0) {
p[i] = idx[pos - 1];
} else {
p[i] = -1;
}
}
int Lmax = len_d;
cout << Lmax << "\n";
// Reconstructia subșirului
// Folosim o stiva (sau array temporar) pentru a inversa ordinea
int* lis_temp = new int[Lmax];
int current_idx = idx[len_d - 1];
int count = 0;
while (current_idx != -1) {
lis_temp[count++] = a[current_idx];
current_idx = p[current_idx];
}
// Afisare in ordine corecta (invers)
for (int i = count - 1; i >= 0; --i) {
cout << lis_temp[i] << (i == 0 ? "" : " ");
}
cout << "\n";
// Eliberarea memoriei
delete[] a;
delete[] d;
delete[] p;
delete[] idx;
delete[] lis_temp;
fclose(fin);
fclose(fout);
}
int main() {
solve();
return 0;
}