Cod sursa(job #2775829)

Utilizator radu.z5Zamfirescu Radu Ioan radu.z5 Data 17 septembrie 2021 15:35:59
Problema Deque Scor 5
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb
#include <stdio.h>
#include <stdlib.h>

struct Pair {
    int val, pos;
};

struct LinkedListNode {
    Pair data;
    LinkedListNode *next;
    LinkedListNode *prev;
};

struct LinkedList {
    LinkedListNode *head;
    LinkedListNode *end;
    size_t size;
};

LinkedList *createLinkedList(void) {
    LinkedList *l = (LinkedList *) calloc(1, sizeof(LinkedList));
    return l;
}

void pushBackIntoList(LinkedList *l, Pair x) {
    LinkedListNode *n = (LinkedListNode *) calloc(1, sizeof(LinkedListNode));
    n->data = x;

    if (l->size == 0UL)
        l->head = n;

    n->prev = l->end;
    l->end = n;

    if (n->prev)
        n->prev->next = n;

    ++(l->size);
}

Pair pollFirstFromList(LinkedList *l) {
    Pair ret = l->head->data;
    LinkedListNode *out = l->head;
    l->head = l->head->next;

    if (l->head) {
        l->head->prev = NULL;
    } else {
        l->end = NULL;
    }

    --(l->size);
    free(out);
    return ret;
}

Pair pollLastFromList(LinkedList *l) {
    Pair ret = l->end->data;
    LinkedListNode *out = l->end;
    l->end = l->end->prev;

    if (l->end) {
        l->end->next = NULL;
    } else {
        l->head = NULL;
    }

    --(l->size);
    free(out);
    return ret;
}

Pair getFirstFromList(LinkedList *l) {
    return l->head->data;
}

Pair getLastFromList(LinkedList *l) {
    return l->end->data;
}

void clearList(LinkedList *l) {
    if (l == NULL)
        return;

    LinkedListNode *x = l->head;

    while (x) {
        LinkedListNode *out = x;
        x = x->next;
        free(out);
    }
    l->head = l->end = NULL;
    l->size = 0UL;
}

long deque(FILE *fin) {
    int n, k;
    fscanf(fin, "%d%d\n", &n, &k);

    long sum = 0L;
    LinkedList *deq = createLinkedList();
    int i, x;

    int firstIdWithinLastSubstr = n - k;
    for (i = 0; i < k; i++) {
        fscanf(fin, "%d\n", &x);
        while (deq->size > 0 && getLastFromList(deq).val >= x)
            pollLastFromList(deq);
        if (deq->size > 0 && i > firstIdWithinLastSubstr)
            continue;
        else
            pushBackIntoList(deq, {x, i});
    }

    sum += getFirstFromList(deq).val;
    if (getFirstFromList(deq).pos == 0)
        pollFirstFromList(deq);

    while (i < n) {
        fscanf(fin, "%d\n", &x);
        while (deq->size > 0 && getLastFromList(deq).val >= x)
            pollLastFromList(deq);
        if (deq->size > 0 && i > firstIdWithinLastSubstr) {
            i++;
            continue;
        }

        pushBackIntoList(deq, {x, i});
        sum += getFirstFromList(deq).val;

        if (getFirstFromList(deq).pos == i - k + 1)
            pollFirstFromList(deq);
        i++;
    }
    clearList(deq);
    free(deq);
    return sum;
}

int main(void) {
    FILE *fin = fopen("deque.in", "r");
    FILE *fout = fopen("deque.out", "w");
    fprintf(fout, "%ld", deque(fin));
    fclose(fin);
    fclose(fout);
    return 0;
}