哈夫曼树(haffman tree)的某题

来源:互联网 发布:淘宝被投诉假货怎么办 编辑:程序博客网 时间:2024/05/11 12:34

今天本弱找到了一个过去的盲点,haffman tree。

写了几个小时才AC, 而且代码长度又被虐, 于是……。


电报公司 code  小明最近新开了一家电报公司。为了在激烈的市场竞争中获取胜利,他果断地找到传说中 X 博士,从他那里买下了传说中的新式电报机。与以往的 2 进制编码机器不同,这台新式的电报机是采用 3 进制编码的。而且,为了尽可能地节约成本,我们要采用尽量好的方式对 26 个字母进行编码,才能尽量节约成本。  编码要在给电文编码之后不会出现多种不同的翻译方式。  比如说,我们有一段电报:abbdcd,那么一种较好的编码方式为:a:01、 b:2、 c:02、 d:1 那么这段电报就可以表示成 01221021,长度为 8。并且编码的内容只对应唯一的一段原文。  现在我们需要你为电报公司设计一个计算器,根据每一个人所要发送的电报内容,计算出所需发送的电报的最短的长度。方便电报公司收取费用。 输入  输入文件第一行有一个数 n ( n≤80000),示电报的内容的长度  第二行有 n 个小写的字母,表示电报的内容 输出  输出一个数,表示最短的长度 样例输入 6 abbdcd 样例输出 8 

懂haffman树的看完此题已经知道如何做的,请按下<Ctrl + W>。


不懂的可以 baidu N叉哈夫曼树算法研究, 稍微导下盲即可。

关于证明我也无能为力

当然再写haffman之前我也曾YY了一个错误算法,

每个顶点分成三叉,每三个儿子中有一个再分为三个儿子,再等等细节 = WA爆  T^T

可耻的code


#include <cstdio>#include <iostream>using namespace std;const int maxn = 100000 + 5;const int maxchar = 26 + 5;class Haffman{#define Memset(a, v) memset(a, v, sizeof(a))   public:      Haffman()      {         r = 0; Memset(s, 0); Memset(p, 0);         Memset(num, 0); Memset(father, 0); Memset(before, 0);      }      int findheight(int u)      {         int h = 0;         while (father[u])          {            u = father[u];            ++h;         }         return h;      }            void initialize()      {         scanf("%d\n", &n);         for (int i=1; i<=n; ++i)         {            char ch; scanf("%c", &ch);            ++num[(int)ch - 'a' + 1];         }         for (int i=1; i<=maxchar; ++i)            if (num[i])             {               s[++r] = num[i];               p[r] = i;               before[r] = 1;            }      }      void maketree()      {         ++r;         int MIN, point;         for (int i=1; i<=3; ++i)         {            MIN = INT_MAX;            for (int j=1; j<=r-1; ++j)            {               if (!father[j] && s[j] < MIN)               {                  MIN = s[j];                  point = j;               }            }            s[r] += MIN;            father[point] = r;         }      }      void work()      {         if (r % 2 == 0)            s[++r] = 0;         int rr = r/2;         for (int i=1; i<=rr; ++i)            maketree();      }      int answer()      {         int ans = 0;         for (int i=1; i<=r; ++i)            if (before[i])            {               int fi = findheight(i);               ans += fi * num[p[i]];            }         return ans;      }   private:      int n, r;      bool before[maxn];      int p[maxn], s[maxn];      int num[maxchar], father[maxn];};Haffman Haffmantree;int main(){   freopen("code.in", "r", stdin);   freopen("code.out", "w", stdout);   Haffmantree.initialize();   Haffmantree.work();   cout << Haffmantree.answer();   return 0;}

第一次写class, 可能丑了点。

此题数据也奉上

http://pan.baidu.com/share/link?shareid=9820&uk=2652110486