Cod sursa(job #2726455)

Utilizator AkrielAkriel Akriel Data 20 martie 2021 23:00:18
Problema Sortare prin comparare Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.29 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>

using namespace std;

const int minConst = 1024;
const int countSortLimit = 1024;

fstream fin("algsort.in");
ofstream fout("algsort.out");

vector<int> initialNumbers;

double EPS = 1e-6;

void countSort(vector<int>& numbers, int minValue, int maxValue){
    auto* freq = new int[maxValue-minValue+1];
    memset(freq, 0, maxValue-minValue+1);
    for (int const &number : numbers){
        freq[number-minValue]++;
    }

    vector<int> res;
    for (int i = 0; i < maxValue-minValue+1; i++){
        for (int j = 0; j < freq[i]; j++){
            res.push_back(i+minValue);
        }
    }

    numbers = res;
}

void akySort(vector<int>& numbers){
    if (numbers.size() < minConst){
        sort(numbers.begin(), numbers.end());
        return;
    }

    int maxValue = numbers[0];
    int minValue = numbers[0];
    for (auto const &el : numbers){
        maxValue = max(maxValue, el);
        minValue = min(minValue, el);
    }

    if (minValue == maxValue){
        return;
    }

    if (maxValue - minValue <= countSortLimit){
        countSort(numbers, minValue, maxValue);
        return;
    }

    //int fragments = max((int)sqrt(maxValue-minValue), 1);
    int fragments = 256;
    double step = (double)(maxValue-minValue) / (double)(fragments);
    auto* buckets = new vector<int>[fragments];
    for (auto const &el : numbers){
        int index = max(min((int)((el-minValue) / step), fragments-1), 0);
        buckets[index].push_back(el);
    }

    vector<int> result;
    for (int i = 0; i < fragments; i++){
        if (buckets[i].empty()) {
            continue;
        }

        if (buckets[i].size() == numbers.size()){
            // sort(bucket.begin(), bucket.end());
            goto push_elem;
        }

        akySort(buckets[i]);

        push_elem:
        for (auto & el : buckets[i]){
            result.push_back(el);
        }
    }
    numbers = result;
}

int main() {
    int n = 1e4;
    fin >> n;
    initialNumbers.resize(n);
    for (auto &el : initialNumbers){
        fin >> el;
//        el = rand();
    }
    akySort(initialNumbers);
//    cout << is_sorted(initialNumbers.begin(), initialNumbers.end());
    for (auto &el : initialNumbers){
        fout << el << " ";
    }
    return 0;
}