C ++ブルーブリッジカップの基本的な練習Huffuman Tree HERODINGのブルーブリッジカップロード

リソース制限
時間制限:1.0秒メモリ制限:512.0 MB
問題の説明
  ハフマンツリーには、コーディングにおける幅広いアプリケーションがあります。ここでは、ハフマンツリーの構築プロセスのみを扱います。
  数値のリスト{pi} = {p0、p1、…、pn-1}が与えられた場合、この数値のリストを使用してハフマンツリーを作成するプロセスは次のとおりです
  。1. {pi}で2つの最小の数値を見つけ、paとpbに設定します。 {pi}からpaとpbを削除し、それらの合計を{pi}に追加します。このプロセスのコストは、pa + pbとして記録されます。
  2. {pi}の数が1つだけになるまで、手順1を繰り返します。
  上記の操作プロセスでは、すべてのコストが加算され、ハフマンツリーを構築するための総コストが取得されます。
  この問題のタスク:特定のシーケンスについて、そのシーケンスでハフマンツリーを構築するための総コストを見つけてください。

たとえば、シーケンス{pi} = {5、3、8、2、9}の場合、ハフマンツリーの構築プロセスは次のようになります
  。1. {5、3、8、2、9}で最小の2つの数値をそれぞれ検索します2と3、それらを{pi}から削除し、5を追加して{5、8、9、5}を取得します。コストは5です。
  2. {5、8、9、5}、5、5の最小の2つの数値を見つけ、{pi}から削除し、10を追加して{8、9、10}を取得します。コストは10です。 。
  3. {8、9、10}の最小の2つの数値(8と9)を見つけ、それらを{pi}から削除し、17を追加して{10、17}を取得します。コストは17です。
  4. {10、17}の中で最も小さい2つの数値(10と17)を見つけ、{pi}から削除し、27を追加して{27}を取得します。コストは27です。
  5.これで、シーケンスに残っている数は27だけです。構築プロセスは終了し、総コストは5 + 10 + 17 + 27 = 59になります。
入力フォーマット入力
  の最初の行には、正の整数n(n <= 100)が含まれています。
  次に、p0、p1、…、pn-1を表すn個の正の整数があり、各数値は1000を超えません。
出力形式
  これらの数値を使用してハフマンツリーを構築するための総コストを出力します。
サンプル入力
5
5 3 8 2 9
サンプル出力
59

問題解決のアイデア:
ハフマンツリーは比較的古典的なアルゴリズムであり、そのアプリケーションシナリオはパスワードの解読と暗号化に非常に成功しています。今日の質問は実際には非常に単純です。貪欲なアイデアで最小の2つの数値を毎回取得し、それをツリーの配列に戻し、配列に要素が1つだけになるまで繰り返します。ここで私は誰もが答えるために2つの方法を使用します。
最初の方法:最小ヒープ、データ構造を学んだ友達は、最小ヒープを書き込むプロセスが非常に難しいことを知っていますが、それは本当に香りがよいと言わなければなりません。すべての入力数値を最初に最小ヒープに入れてくださいヒープの最上位の要素が最小のヒープから取得されるたびに、最小値である必要があります。以下同様に、ヒープ内の要素が1つだけになるまで続きます。
2番目の方法:sort()関数を使用して並べ替え、毎回最小の要素を取得し、余分な要素を削除するように注意します。

2つの方法があります。

#include<bits/stdc++.h>

using namespace std;

template<class T>
class MinHeap {
private:
	T *heapArray;			// 存放堆数据的数组
	int CurrentSize;			// 当前堆中元素数目
	int MaxSize;			// 堆所能容纳的最大元素数目
public:
	MinHeap(const int n);			// 构造函数,n表示 堆的最大元素数目
	virtual ~MinHeap() { delete[]heapArray; }	// 析构函数
	void swap(int pos_x, int pos_y);	// 交换位置x和y的元素
	void BuildHeap();			// 建堆
	bool isEmpty();			// 如果堆空,则返回真
	bool isLeaf(int pos) const;	    		// 如果是叶结点,返回TRUE
	int leftchild(int pos) const;	   		// 返回左孩子位置
	int rightchild(int pos) const;		// 返回右孩子位置
	int parent(int pos) const;			// 返回父结点位置
	bool Remove(int pos, T& node); 		// 删除给定下标的元素
	bool Insert(const T& newNode);		// 向堆中插入新元素newNode
	T& RemoveMin();			// 从堆顶删除最小值
	void SiftUp(int position);		 // 从position向上开始调整,使序列成为堆
	void SiftDown(int left);         	// 向下筛选,参数left表示开始处理的数组下标
	void show();
	int getCurrentSize();
};

template<class T>
int MinHeap<T>::getCurrentSize() {
	return CurrentSize;
}


template<class T>
bool MinHeap<T>::isEmpty() {
	if (CurrentSize == 0) {
		return true;
	}
	else return false;
}

template<class T>
bool MinHeap<T>::isLeaf(int pos) const {
	if (pos % 2 == 1) {
		return true;
	}
	else return false;
}

template<class T>
void MinHeap<T>::swap(int pos_x, int pos_y) {
	T data = heapArray[pos_x];
	heapArray[pos_x] = heapArray[pos_y];
	heapArray[pos_y] = data;
}

template<class T>
void MinHeap<T>::BuildHeap() {
	for (int i = CurrentSize / 2 - 1; i >= 0; i--)// 反复调用筛选函数
		SiftDown(i);
}


template<class T>
MinHeap<T>::MinHeap(const int n) {
	if (n <= 0)     return;
	CurrentSize = 0;
	MaxSize = n;				// 初始化堆容量为n
	heapArray = new T[MaxSize];		// 创建堆空间
	BuildHeap();  // 此处进行堆元素的赋值工作
}

template<class T>
int MinHeap<T>::leftchild(int pos) const {
	return 2 * pos + 1;					 	// 返回左孩子位置
}

template<class T>
int MinHeap<T>::rightchild(int pos) const {
	return 2 * pos + 2;					   	// 返回右孩子位置
}
template<class T>
int MinHeap<T>::parent(int pos) const {
	return (pos - 1) / 2;				   		// 返回父结点位置
}

template <class T>
bool MinHeap<T>::Insert(const T& newNode) { // 向堆中插入新元素newNode
	if (CurrentSize == MaxSize)	return false; // 堆空间已经满
	heapArray[CurrentSize] = newNode;
	SiftUp(CurrentSize);					// 向上调整
	CurrentSize++;
	return true;
}

template<class T>
T& MinHeap<T>::RemoveMin() {	// 从堆顶删除最小值
	if (CurrentSize == 0) {
		cout << "Can't Delete";		// 调用RemoveMin之前,需要判断堆非空
		exit(1);
	}
	else {
		swap(0, --CurrentSize);	                 // 交换堆顶和最后一个元素
		if (CurrentSize > 1) {
			SiftDown(0);   // 从堆顶开始筛选
		}
		return heapArray[CurrentSize];
	}
}
template<class T>
bool MinHeap<T>::Remove(int pos, T& node) {   	// 删除给定下标的元素
	if ((pos < 0) || (pos >= CurrentSize))     return false;
	node = heapArray[pos];
	heapArray[pos] = heapArray[--CurrentSize];	// 用最后的元素值替代删除位置的元素
	if (heapArray[parent(pos)] > heapArray[pos])
		SiftUp(pos);			// 当前元素小于父结点,需要上升调整
	else SiftDown(pos);			// 当前元素大于父结点,向下筛
	return true;
}

template<class T>
void MinHeap<T>::SiftUp(int position) {
	// 从position向上开始调整
	int temppos = position;
	T temp = heapArray[temppos];
	while ((temppos > 0) && (heapArray[parent(temppos)] > temp)) {
		heapArray[temppos] = heapArray[parent(temppos)];
		temppos = parent(temppos);
	}
	heapArray[temppos] = temp;
}

template <class T>
void MinHeap<T>::SiftDown(int left) {
	int i = left;			// 标识父结点
	int j = leftchild(i); 			// 标识关键值较小的子结点
	T temp = heapArray[i];		// 保存父结点
	while (j < CurrentSize) {       		// 过筛
		if ((j < CurrentSize - 1) && (heapArray[j] > heapArray[j + 1]))
			//若有右子节点,且小于左子节点
			j++;							// j指向右子结点
		if (temp > heapArray[j]) {  //若父节点大于子节点的值则交换位置
			heapArray[i] = heapArray[j];
			i = j;
			j = leftchild(j);
		}
		else break;  //堆序满足,跳出
	}
	heapArray[i] = temp;
}

template<class T>
void MinHeap<T>::show() {
	for (int i = 0;i < CurrentSize; i++)
	{
		cout << heapArray[i] << " ";
	}
}
int main() {
	MinHeap<int> heap(100);
	int i, n;
	cin >> n; 
	for(i = 0; i < n; i++) {
		int data;
		cin >> data;
		heap.Insert(data);
	}
	int sum = 0;
	int num = 0;
	while(heap.getCurrentSize() > 1){
		num += heap.RemoveMin();
		num += heap.RemoveMin();
		sum += num;
		heap.Insert(num);
		num = 0;
	} 
	cout << sum;
	return 0;
}
#include<bits/stdc++.h>

using namespace std;

int main()
{
    int a[100];
    int i,n;
    cin >> n;
    for(i = 0; i < n; i++) {
    	cin >> a[i];
	}
    sort(a,a+n);//从小到大排序
    int sum = 0;
    while(n > 1)
    {
        i=0;
        a[i] = a[i] + a[i+1];
        sum += a[i];
        a[i + 1] = -1;//将这个数去除
        sort(a,a+n);
        for(i = 0;i < n-1; i++)//把-1值覆盖 
            a[i] = a[i+1];
    n--;
}
    cout << sum;
    return 0;
}

元の記事を7件公開 8 件を獲得 804件を表示

おすすめ

転載: blog.csdn.net/HERODING23/article/details/105673503