Cod sursa(job #1454450)

Utilizator GilgodRobert B Gilgod Data 26 iunie 2015 16:57:06
Problema Radix Sort Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 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[NMAX];
int W[NMAX];
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[1] = B % C;
	for (int i = 2; i <= N; ++i)
		V[i] = ((long long)A %C * V[i - 1] %C + B) % C;
	fclose(stdin);
}

int get_byte(int const el, int const byte) 
{ 
	return (el >> byte * 8) & MAXBYTE;
}

int counter[BYTE_VARIATIONS];
int indexer[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));
	//indexer-ul de start pentru fiecare cheie
	memset(indexer, 0, sizeof(indexer));
	
	//calculul histogramei
	for (int i = 1; i <= N; ++i) {
		++counter[get_byte(source[i], byte)];
	}

	//calculul indexerului 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");
	fclose(stdout);
	return 0;
}