Cod sursa(job #2706422)

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

const int MAX_N = 10000000;
const int NO_BUCKETS = (1 << 8);

uint32_t numbers[MAX_N];
uint32_t temp[MAX_N];

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 uint32_t get_byte(uint32_t number, int byte) {
    uint32_t mask = 0xFF;
    return ((number >> (byte * 8)) & mask);
}

void countsort(int n, uint32_t * numbers, 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, uint32_t * numbers) {
    for (int i = 0; i < sizeof(uint32_t); i++) {
        if (i % 2 == 0) {
            countsort(n, numbers, temp, i);
        } else {
            countsort(n, temp, numbers, 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);

    numbers[0] = b % c;
    for (int i = 1; i < n; i++) {
        numbers[i] = (1LL * 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;
}