Cod sursa(job #2706438)

Utilizator vnedelcuVictor Andrei Nedelcu vnedelcu Data 14 februarie 2021 21:57:01
Problema Radix Sort Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <inttypes.h>

using namespace std;

const int NO_BUCKETS = 1 << 8;

class BufferedWriter{
private:
    FILE * f;
    char * buffer;
    static const int BUFF_MAX_SIZE;
    int buff_size;

public:
    BufferedWriter(const char * file_name);
    ~BufferedWriter();
    void write_chr(char ch);
    void write_u32(uint32_t num);
    void write_buff_contents();
};

const int BufferedWriter::BUFF_MAX_SIZE = 1 << 15;

BufferedWriter::BufferedWriter(const char * file_name) {
    f = fopen(file_name, "w");
    buffer = (char * ) malloc(BUFF_MAX_SIZE);
    buff_size = 0;
}

BufferedWriter::~BufferedWriter() {
    free(buffer);
    fclose(f);
}

void BufferedWriter::write_chr(char ch) {
    if (buff_size == BUFF_MAX_SIZE) {
        fwrite(buffer, 1, BUFF_MAX_SIZE, f);
        buff_size = 0;
    }
    buffer[buff_size++] = ch;
}

void BufferedWriter::write_u32(uint32_t num) {
    if (num <= 9) {
        write_chr(num + '0');
        return;
    }
    write_u32(num / 10);
    write_chr(num % 10 + '0');
}

void BufferedWriter::write_buff_contents() {
    if (buff_size > 0) {
        fwrite(buffer, 1, buff_size, f);
    }
}

inline int get_byte(uint32_t number, int byte) {
    return ((number >> (byte * 8)) & 0xFFu);
}

void countsort(int n, vector<uint32_t> & numbers, vector<uint32_t> & temp, int byte) {
    int buckets[NO_BUCKETS] = {0};

    for (int j = 0; j < n; j++) {
        buckets[get_byte(numbers[j], byte)]++;
    }
    for (int j = 1; j < NO_BUCKETS; j++) {
        buckets[j] += buckets[j - 1];
    }
    for (int j = n - 1; j >= 0; j--) {
        temp[--buckets[get_byte(numbers[j], byte)]] = numbers[j];
    }
}

void radixsort(int n, vector<uint32_t> & numbers) {
    vector<uint32_t> temp(n);

    for (int i = 0; i < sizeof(uint32_t); i++) {
        if (i & 1) {
            countsort(n, temp, numbers, i);
        } else {
            countsort(n, numbers, temp, i);
        }
    }
}

int main() {
    int n, a, b, c;
    FILE * f;

    f = fopen("radixsort.in", "r");
    fscanf(f, "%d%d%d%d", &n, &a, &b, &c);
    fclose(f);

    vector<uint32_t> numbers(n);
    numbers[0] = b % c;
    for (int i = 1; i < n; i++) {
        numbers[i] = (((uint64_t) a) * numbers[i - 1] % c + b) % c;
    }

    radixsort(n, numbers);

    BufferedWriter buffered_writer("radixsort.out");
    for (int i = 0; i < n; i += 10) {
        buffered_writer.write_u32(numbers[i]);
        buffered_writer.write_chr(' ');
    }
    buffered_writer.write_buff_contents();

    return 0;
}