Mai intai trebuie sa te autentifici.
Cod sursa(job #2811673)
Utilizator | Data | 2 decembrie 2021 20:54:31 | |
---|---|---|---|
Problema | Deque | Scor | 0 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 3.97 kb |
#include <iostream>
#include <fstream>
using namespace std;
ifstream f("deque.in");
ofstream g("deque.out");
int a[500010];
struct Deque
{
int x; // last
int y; // first
int dim;
int index;
int deq[100010];
};
void push(int e, Deque &d)
{
d.dim++;
d.deq[d.index + d.dim - 1] = e;
}
void poplast(Deque &d)
{
if(d.dim>0)
{
d.dim--;
}
}
void popfirst(Deque &d)
{
if(d.dim > 0)
{
d.dim--;
d.index++;
}
}
int getFirst(Deque& d) { // AICI AM PUS FUNCTIILE ASTEA CARE SA ITI DEA PRIMUL SI ULTIMUL, CA TE AMETEAI DACA LE CALCULAI
return d.deq[d.index]; // TOT IN POP/PUSH
} // FUNCTIILE ASTEA SUNT CORECTE DOAR DACA STIVA NU E GOALA
int getLast(Deque& d){
return d.deq[d.index + d.dim - 1];
}
int isEmpty(Deque& d){
if(d.dim == 0){
return true;
}
return false;
}
Deque stivadubla;
int n,k,s;
void info(){
cout<<"\nStiva contine:\n";
for(int i = 0 ; i < stivadubla.index + stivadubla.dim + 10; i++){
cout<< a[stivadubla.deq[i]] << " ";
}
cout<<"\n index = " << stivadubla.index << " dimensiune = "<< stivadubla.dim << " x = last = " << a[stivadubla.x] << " y = first =" << a[stivadubla.y] << "\n";
for(int i = stivadubla.index ; i < stivadubla.index + stivadubla.dim; i++){
cout<< a[stivadubla.deq[i]] << " ";
}
cout <<"\n";
}
int main()
{
stivadubla.y=0;
stivadubla.x=0;
stivadubla.dim=0;
stivadubla.index=0;
f>>n>>k;
for(int i=0;i<n;i++)
f>>a[i];
push(0,stivadubla); // ACUM CA NU MAI DAI POP CU STIVA GOALA, POTI SA INCEPI FOR-UL de la 0, sa nu mai dai push aici
// cele 3 componente sunt asa:
// - adaugare nomala in deque: se face la fecare pas
// - expirarea unui element din deque: cand deque.first == index - k
// - gasirea minimului pe o subsecventa de k: se face la fiecare pas, odata ce index >= k-1
for(int i = 1; i < n; i++)
{
if(isEmpty(stivadubla)==true || a[i]>a[getLast(stivadubla)])
{
push(i,stivadubla);
}
else
{
while(!isEmpty(stivadubla) && a[getLast(stivadubla)]>a[i]) //TU DADEAI POP SI DACA STIVA ERA GOALA
{
poplast(stivadubla);
}
push(i,stivadubla);
}
if(!isEmpty(stivadubla) && getFirst(stivadubla) + k == i) //expirarea // SI AICI LA FEL< PUTEA FI STIVA GOALA
{
popfirst(stivadubla);
}
if(i >= k - 1) // SI AICI MINUMUL SE CALCULEAZA DOAR DUPA CE TREC k ELEMENTE
{
s += a[getFirst(stivadubla)];
}
}
cout<<"\ns="<<s;
return 0;
}
/*
Solutia1
parcurg lista de la 1 la n cu un iterator i si apoi in el
parcurg cu un iterator j de la i la k+i si retin min pe secventa parcursa de j
*/
///complexitate: n*k;
/*
Solutia2
Not cu x=ultimul elem din deque la fiecare pas
Not cu y=primul elem din deque la fiecare pas
parcurgem sirul cu un iterator i:
-si testam daca ultimul element din deque este mai mic decat a[i] adica: a[x] < a[i]?
-daca este, il bagam pe i in deque la sfarsit (ca sa tinem minte pozitia): a[x] < a[i]
-daca nu este, -il pop pe ultimul element din deque cat timp este mai mic decat a[i] (a[x]<a[i])
-il bagam pe i in deque
-cand head-ul din deque plus k este egal cu i, atunci il pop pe head;
*/
///complexitate: n
///pt ca la fiecare pas cand pop uieste elem dinainte ptc sunt mai mari, nu are cum sa pop uiasca k elemente la fiecare element bagat
///de ex daca k=6 are a b c d e si vrea sa il bage pe f (toate sunt mai mari si le da pop) dupa in deque o sa il aiba doar pe f si nu o sa mai aiba cum sa
///pop uiasca tot k-1 elemente ca e doar f acolo therefore nu are cum sa fie complexitatea n*(k-1)