Cod sursa(job #3370138)

Utilizator DavidLDavid Lauran DavidL Data 24 octombrie 2026 11:49:25
Problema Sortare prin comparare Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.69 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("algsort.in");
ofstream fout("algsort.out");

inline int getRandomNumber(int lowerBound, int upperBound) {
    return lowerBound + rand() % (upperBound - lowerBound + 1);
}

class Sorter {
public:
    virtual vector<int> sort(const vector<int>& numbers) const = 0;

    virtual ~Sorter() = default;
};

class MergeSorter : public Sorter {
public:
    vector<int> sort(const vector<int>& numbers) const override {
        vector<int> sortedNumbers(numbers);
        sort(sortedNumbers, 0, (int)numbers.size() - 1);
        return sortedNumbers;
    }

private:
    void sort(vector<int>& numbers, int leftIndex, int rightIndex) const {
        // cout << leftIndex << " " << rightIndex << "\n";
        if (leftIndex >= rightIndex) {
            return;
        }

        int middleIndex = (leftIndex + rightIndex) / 2;
        sort(numbers, leftIndex, middleIndex);
        sort(numbers, middleIndex + 1, rightIndex);
        merge(numbers, leftIndex, rightIndex);
    }

    void merge(vector<int>& numbers, int leftIndex, int rightIndex) const {
        if (leftIndex >= rightIndex) {
            return;
        }

        int middleIndex = (leftIndex + rightIndex) / 2;

        vector<int> mergedValues(rightIndex - leftIndex + 1);
        int mergedValuesIndex = 0;

        int currentLeftHalfIndex = leftIndex;
        int currentRightHalfIndex = middleIndex + 1;
        while (currentLeftHalfIndex <= middleIndex && currentRightHalfIndex <= rightIndex) {
            if (numbers[currentLeftHalfIndex] <= numbers[currentRightHalfIndex]) {
                mergedValues[mergedValuesIndex++] = numbers[currentLeftHalfIndex++];
            } else {
                mergedValues[mergedValuesIndex++] = numbers[currentRightHalfIndex++];
            }
        }
        while (currentLeftHalfIndex <= middleIndex) {
            mergedValues[mergedValuesIndex++] = numbers[currentLeftHalfIndex++];
        }
        while (currentRightHalfIndex <= rightIndex) {
            mergedValues[mergedValuesIndex++] = numbers[currentRightHalfIndex++];
        }

        for (int i = leftIndex; i <= rightIndex; i++) {
            numbers[i] = mergedValues[i - leftIndex];
        }
    }
};

class QuickSorter : public Sorter {
public:
    QuickSorter() {
        srand(time(NULL));
    }

    vector<int> sort(const vector<int>& numbers) const override {
        vector<int> sortedNumbers(numbers);
        sort(sortedNumbers, 0, numbers.size() - 1);
        return sortedNumbers;
    }

private:
    void sort(vector<int>& numbers, int leftIndex, int rightIndex) const {
        if (leftIndex >= rightIndex) {
            return;
        }
        int pivotIndex = getRandomNumber(leftIndex, rightIndex);

        // put the pivot on its correct index
        int countLowerThanPivot = countLowerThan(numbers, leftIndex, rightIndex, numbers[pivotIndex]);
        int correctPivotIndex = leftIndex + countLowerThanPivot;
        swap(numbers[pivotIndex], numbers[correctPivotIndex]);
        pivotIndex = correctPivotIndex;

        arrangeNumbersAroundCorrectlyPlacedPivot(numbers, leftIndex, rightIndex, pivotIndex);

        sort(numbers, leftIndex, pivotIndex - 1);
        sort(numbers, pivotIndex + 1, rightIndex);
    }

    // Ensures all numbers smaller than the pivot are before the correctly placed pivot (which implies that all larger or equal numbers are afterwards)
    void arrangeNumbersAroundCorrectlyPlacedPivot(vector<int>& numbers, int leftIndex, int rightIndex, int pivotIndex) const {
        int currentLeftHalfIndex = leftIndex;
        int currentRightHalfIndex = pivotIndex + 1;
        while (currentLeftHalfIndex < pivotIndex) {
            if (numbers[currentLeftHalfIndex] >= numbers[pivotIndex]) {
                swap(numbers[currentLeftHalfIndex], numbers[currentRightHalfIndex]);
                currentRightHalfIndex++;
            } else {
                currentLeftHalfIndex++;
            }
        }
    }

    static int countLowerThan(const vector<int>& numbers, int leftIndex, int rightIndex, int threshold) {
        int count = 0;
        for (int i = leftIndex; i <= rightIndex; i++) {
            if (numbers[i] < threshold) {
                count++;
            }
        }
        return count;
    }
};

void sortAndPrint(const vector<int>& numbers, const Sorter& sorter) {
    vector<int> sortedNumbers = sorter.sort(numbers);
    // cout << "printing with size " << sortedNumbers.size() << "\n";
    for (int number : sortedNumbers) {
        fout << number << " ";
    }
}

int main() {
    int n;
    fin >> n;
    vector<int> numbers(n);
    for (int i = 0; i < n; i++) {
        fin >> numbers[i];
    }

    sortAndPrint(numbers, QuickSorter());

    return 0;
}