Cod sursa(job #1521983)

Utilizator DanFodorFODOR Dan Horatiu DanFodor Data 11 noiembrie 2015 03:24:08
Problema Sortare prin comparare Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 3.46 kb
#include <cstdio>
#include <queue>

using namespace std;

struct Point {
    int start, fin;
};

int a[500012];

int main()
{
    FILE * inFile, *outFile;

    inFile = fopen ("algsort.in","r");
    outFile = fopen ("algsort.out", "w+");

    int n, x, y, prev;
    fscanf(inFile, "%d", &n);
    if (n <= 2)
    {
        if (n == 1)
        {
            fscanf(inFile, "%d", &x);
            fprintf(outFile, "%d\n", x);
        }
        if (n == 2)
        {
            fscanf(inFile, "%d %d", &x, &y);
            fprintf(outFile, "%d %d", min(x, y), max(x, y));
        }
    }
    else
    {
        queue <Point> q;

        Point p;
        p.start = 0;
        p.fin = 0;

        bool poz, ch = false;
        fscanf(inFile, "%d %d", &x, &y);
        a[0] = x;
        a[1] = y;
        poz = true;
        if (x > y)
            poz = false;
        prev = y;
        p.fin = 1;
        for (int i = 2; i < n; i++)
        {
            fscanf(inFile, "%d", &x);
            a[i] = x;
            if (ch == true)
            {
                poz = false;
                if (prev < x)
                    poz = true;
                ch = false;
            }

            if ((prev < x) == poz)
            {
                ++p.fin;
            }
            else
            {
                q.push(p);
                if (poz == false)
                {
                    int finish = (p.start + (p.fin  - p.start + 1) / 2);
                    for (int j = p.start; j < finish; ++j)
                    {
                        swap(a[j], a[finish + p.start - j]);
                    }
                }
                ch = true;
                p.start = i;
                p.fin = i;
            }

            prev = x;
        }
        q.push(p);
        if (poz == false)
        {
            for (int j = p.start; j < (n + p.start) / 2; ++j)
            {
                swap(a[j], a[n + p.start - j - 1]);
            }
        }

        bool even = true;
        int len = q.size();

        if (len % 2 != 0)
            even = false;

        int take = (len + 1) / 2;

        while (len != 1)
        {
            if (even == false)
                --take;
            for (int i = 0; i < take; ++i)
            {
                Point p1, p2;
                p1 = q.front();
                q.pop();
                p2 = q.front();
                q.pop();

                Point newP;
                newP.start = p1.start;
                newP.fin = p2.fin;
                q.push(newP);

                int lb1 = p1.start;
                int lb2 = p2.start;
                int up2 = p2.fin;
                for (lb2; lb2 <= up2; ++lb2)
                {
                    int j = lb2;
                    while (lb1 <= (j - 1) && a[j - 1] > a[j])
                    {
                        swap (a[j-1], a[j]);
                        --j;
                    }
                }
            }
            if (even == false)
            {
                Point z = q.front();
                q.pop();
                q.push(z);
            }

            len = q.size();
            take = (len + 1) / 2;
            even = true;
            if (len % 2 != 0)
                even = false;
        }
        for (int i = 0; i < n; ++i)
            fprintf(outFile, "%d ", a[i]);
        fprintf(outFile, "\n");
    }

    return 0;
}