Cod sursa(job #2888850)

Utilizator widzAndrei-Daniel Tava widz Data 11 aprilie 2022 21:41:24
Problema Coduri Huffman Scor 65
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
#include <queue>


using namespace std;

struct node
{
	long long val;
	node* parent;
	node(long long v = 0, node* p = nullptr) : val(v), parent(p) {};
};

pair<int, unsigned long long> getCode(node* nod)
{
	int lung = 0;
	unsigned long long cod = 0;
	int pow = 1;
	while (nod->parent != nullptr)
	{
		++lung;
		if (nod->val < 0)
			cod += pow;
		pow *= 2;
		nod = nod->parent;

	}
	return make_pair(lung, cod);
}

int main()
{
	ifstream in("huffman.in");
	ofstream out("huffman.out");
	int nodes;
	long long freq;
	long long lg = 0;
	vector<node*> symbol_q;
	queue<node*> internal_q;

	in >> nodes;
	for (int i = 0; i < nodes; ++i)
	{
		in >> freq;
		symbol_q.push_back(new node(freq, nullptr));
	}
	int pos = 0;
	while (pos < nodes || internal_q.size() > 1)
	{
		node* min1, * min2;
		if (pos == nodes)
		{
			min1 = internal_q.front();
			internal_q.pop();
			min2 = internal_q.front();
			internal_q.pop();
			lg += min1->val + min2->val;
		}
		else if (internal_q.empty())
		{
			min1 = symbol_q[pos];
			++pos;
			min2 = symbol_q[pos];
			++pos;
		}
		else
		{
			if (symbol_q[pos]->val <= internal_q.front()->val)
			{
				min1 = symbol_q[pos];
				++pos;
			}
			else
			{
				min1 = internal_q.front();
				internal_q.pop();
				lg += min1->val;
			}
			if (pos < nodes && !internal_q.empty())
			{
				if (pos < nodes && symbol_q[pos]->val <= internal_q.front()->val)
				{
					min2 = symbol_q[pos];
					++pos;
				}
				else
				{
					min2 = internal_q.front();
					internal_q.pop();
					lg += min2->val;
				}
			}
			else
			{
				if (pos == nodes)
				{
					min2 = internal_q.front();
					internal_q.pop();
					lg += min2->val;
				}
				else
				{
					min2 = symbol_q[pos];
					++pos;
				}
			}

		}

		internal_q.push(new node(min1->val + min2->val, nullptr));
		min1->parent = internal_q.back();
		min2->val *= -1;
		min2->parent = internal_q.back();

	}
	lg += internal_q.front()->val;
	in.close();
	out << lg << "\n";
	for (auto symbol : symbol_q)
	{
		auto res = getCode(symbol);
		out << res.first << " " << res.second << "\n";
	}

}