Cod sursa(job #1454438)

Utilizator GilgodRobert B Gilgod Data 26 iunie 2015 16:44:03
Problema Radix Sort Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <iostream>
#include <fstream>
#include <assert.h>
#include <cstring>

const char IN[] = "radixsort.in", OUT[] = "radixsort.out";
const int NMAX = 10000001;
const int BYTE_COUNT = sizeof(int);	//4
const int BYTE_VARIATIONS = 1 << 8; //2^8
const short MAXBYTE = 0xFF;

using namespace std;

int *V;
int *W;
int N, A, B, C;

inline void read_data() {
	assert(freopen(IN, "r", stdin));
	assert(scanf("%d %d %d %d", &N, &A, &B, &C));
	V = new int[N + 1];
	W = new int[N + 1];
	V[1] = B % C;

	for (int i = 2; i <= N; ++i)
		V[i] = ((long long)A %C * V[i - 1] %C + B) % C;
	fclose(stdin);
}

const short get_byte(int const el, int const byte) 
{ 
	return el & (MAXBYTE << byte);
}

int counter[BYTE_VARIATIONS];
int index[BYTE_VARIATIONS];

//sorteaza dupa un octet prin numarare
//cheile vor fi valori intre 0..255
inline void counting_sort(int* source, int *dest, int byte) {
	//histograma frecventei cheilor
	memset(counter, 0, sizeof(counter));
	//index-ul de start pentru fiecare cheie
	memset(index, 0, sizeof(index));
	
	//calculul histogramei
	for (int i = 1; i <= N; ++i) {
		++counter[get_byte(source[i], byte)];
	}

	//calculul indexului de start pentru fiecare cheie
	int total = 0;
	for (int i = 0; i <= MAXBYTE; ++i) {
		int oldcount = counter[i];
		counter[i] = total;
		total += oldcount;
	}

	//se copiaza rezultatul in destinatie
	for (int i = 1; i <= N; ++i) {
		dest[counter[get_byte(source[i], byte)]+1] = source[i];
		++counter[get_byte(source[i], byte)];
	}
}

inline void radix_sort() {
	//sorteaza pe rand octetii(de la cel mai putin semnificativ),
	//alternand sursa si destinatia
	//la final dupa 4 iteratii solutia o sa fie in V
	for (int byte = 0; byte < BYTE_COUNT; ++byte) {
		if (byte & 1) counting_sort(W, V, byte);
		else counting_sort(V, W, byte);
	}
}

int main() {
	read_data();
	radix_sort();
	assert(freopen(OUT, "w", stdout));
	for (int i = 1; i <= N; i +=10) printf("%d ", V[i]);
	printf("\n");
	delete[] V;
	delete[] W;
	fclose(stdout);
	return 0;
}