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);
    }
    


  • 相关阅读:
    升级安装 Ubuntu 后该做的20项优化工作
    Delphi中点击DBGrid某一行获得其详细数据方法
    android eclipse xml不自动代码提示
    区别不同浏览器,CSS hack写法
    自我介绍
    秋季学期学习总结
    人生路上影响最大的三位老师
    SQL优化34条
    Visual Studio 2010将支持多种架构设计图
    Visual Studio 2010的SharePoint工作流功能
  • 原文地址:https://www.cnblogs.com/pangblog/p/3279815.html
Copyright © 2011-2022 走看看