zoukankan      html  css  js  c++  java
  • HDU 2527

    题目描述

             HDU 2527

    分析

            霍夫曼编码的应用。
            本题没有必要构造一棵完整的霍夫曼树。只需利用霍夫曼编码的原理,每次挑选频率最低的两个元素进行合并。(显然,可以利用优先级队列,这里用数组来模拟)

    源码

            
    //每次挑出现频率最小的两个元素,应该用优先级队列!!!!!!!!!!
    
    #include <stdio.h>
    #include <limits.h>
    #include <string.h>
    int unionFre(int fre[26]);
    
    int main()
    {
    	int frequency[26];    //记录每个字母出现的频率
    	int n;
    	int m;
    	char input[10000];
    	int letterNum;     //出现的小写字母的个数
    	int len;
    	int result;
    	int i, j;
    
    	scanf("%d", &n);
    	while (n --)
    	{
    		scanf("%d", &m);
    		scanf("%s", &input);
    		//初始化
    		memset(frequency, 0, sizeof(frequency));
    
    		//统计每个字母出现的次数
    		len = strlen(input);
    		for (i = 0; i < len; i ++)
    		{
    			frequency[input[i]-'a'] ++;
    		}
    		//没出现的字母频率均设为最大值
    		letterNum = 26;
    		for (i = 0; i < 26; i ++)
    		{
    			if (frequency[i] == 0)
    			{
    				letterNum --;
    				frequency[i] = INT_MAX;
    			}
    		}
    
    		//如果字符串只由一个字母组成
    		if (letterNum == 1)
    		{
    			result = frequency[input[0]-97];
    			if (result <= m)
    				printf("yes
    ");
    			else
    				printf("no
    ");
    
    			continue;
    		}
    
    		//循环(letterNum-1)次,每次挑选出现频率最低的两个元素进行合并
    		//并更新result值,加上被合并的两个元素的频率和
    		result = 0;
    		for (i = 0; i < letterNum-1; i ++)
    		{
    			result = result + unionFre(frequency);
    		}
    
    		if (result <= m)
    			printf("yes
    ");
    		else
    			printf("no
    ");
    	}
    
    	return 0;
    }
    
    //合并函数
    int unionFre(int fre[26])
    {
    	int min, secondMin;
    	int minIndex, secondMinIndex;
    	int temp;
    	int i;
    
    	min = fre[0];
    	minIndex = 0;
    	secondMin = fre[1];
    	secondMinIndex = 1;
    
    	if (min > secondMin)
    	{
    		temp = min;
    		min = secondMin;
    		secondMin = temp;
    
    		temp = minIndex;
    		minIndex = secondMinIndex;
    		secondMinIndex = temp;
    	}
    
    	//找出频率最低的两个元素
    	for (i = 2; i < 26; i ++)
    	{
    		if (fre[i] < min)
    		{
    			secondMin = min;
    			secondMinIndex = minIndex;
    
    			min = fre[i];
    			minIndex = i;
    		}
    		else if (fre[i] < secondMin)
    		{
    			secondMin = fre[i];
    			secondMinIndex = i;
    		}
    	}
    
    	//合并两个元素
    	fre[minIndex] = min + secondMin;
    	fre[secondMinIndex] = INT_MAX;
    
    	return (min + secondMin);
    }
    


  • 相关阅读:
    poj3348 Cow
    poj3348 Cow
    日常。。。强行续
    日常。。。又又续
    日常。。。又又续
    日常。。。又续
    内存检索
    MyLayer MyScene
    冒泡排序
    Array数组的排序与二分查字法
  • 原文地址:https://www.cnblogs.com/pangblog/p/3279815.html
Copyright © 2011-2022 走看看