Cod sursa(job #1065858)

Utilizator ELHoriaHoria Cretescu ELHoria Data 23 decembrie 2013 19:16:45
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
#include <fstream>
#include <queue>
#include <algorithm>
#include <vector>
#include <functional>

using namespace std; 

struct Node {
	Node *leftSon;
	Node *rightSon;
	long long weight;
	Node(Node *ls ,Node *rs,long long w) {
		leftSon = ls;
		rightSon = rs;
		weight = w;
	}
};

vector< pair<int,long long> > A;

inline void rev(long long &val,int l) {
	for (int i = 0;i < (l >> 1);i++) {
		if ( ((val >> (i*1LL) ) & 1) != ((val >> (1LL * (l - i - 1))) & 1) ) {
			val ^= (1LL << i);
			val ^= (1LL << (l - i - 1));
		}
	}
}

void gen(long long code,int l,ostream &cout) {
	for (int i = l - 1;i >= 0;i--) {
		cout << ( (code >> (1LL * i)) & 1);
	}
	cout << "\n";
}

void print(Node *node,long long code,int depth,ostream &cout) {
	if (node -> leftSon == NULL && node -> rightSon == NULL) {
		A.push_back( make_pair(depth,code));
		return;
	}

	if (node -> leftSon != NULL) {
		print(node -> leftSon,code,depth + 1,cout);
	}

	if (node -> rightSon != NULL) {
		print(node -> rightSon,code | 1LL << depth,depth + 1,cout);
	}
	
}

int main()
{
	ifstream cin("huffman.in");
	ofstream cout("huffman.out");
    queue< Node* > Q[2];
	int n, w;
	long long ans = 0;
	Node *root;
	cin >> n;
	for (int i = 0;i < n;i++) {
		cin >> w;
		Q[0].push( root = new Node(NULL,NULL,w));
	}

	while (Q[0].size() + Q[1].size() > 1) {
		Node *node[2];
		for (int k = 0;k < 2;k++) {
			if (!Q[0].empty() && !Q[1].empty()) {
				if (Q[0].front()->weight <= Q[1].front()->weight) {
					node[k] = Q[0].front();
					Q[0].pop();
				} else {
					node[k] = Q[1].front();
					Q[1].pop();
				}
			} else 
			if (!Q[0].empty()) {
				node[k] = Q[0].front();
				Q[0].pop();
			} else {
				node[k] = Q[1].front();
				Q[1].pop();
			}
		}

		root = new Node(node[0],node[1],node[0]->weight + node[1]->weight);
		ans += root->weight;
		Q[1].push(root);
	}

	cout << ans<< "\n";
	print(root,0,0,cout);
	sort (A.begin(),A.end(),greater< pair<int,long long> > ());
	for (int i = 0;i < n;i++) {
		rev (A[i].second,A[i].first);
		cout << A[i].first << " " << A[i].second << "\n";
		//gen(A[i].second,A[i].first,cout);
	}
	return 0;
}