user-0 提问: 霍夫曼编码入门

回复:
user: user-1
content: 引用 5 楼 qq_36790578 的回复:这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 你用快速排序每次必须重排整个数组，单次操作nlogn，整体复杂度就n^2logn 而用堆只是操作两三个元素，并不碰其他无关的元素，单次操作O(logn)。 堆调节并不是对整个数组重新做堆排序。如果对整个数组做堆排序的话那和你的快排是一样慢的。

user: user-2
content: 引用 5 楼 qq_36790578 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] #include <stdio.h> #include <stdlib.h> #include <ctype.h>  int c;  int get() {     int num = 0;     while (isdigit(c = getchar())) {         num = num * 10 + c - '0';     }     return num; } int a[105];  void swap(int *a, int *b) {     int t = *a;     *a = *b;     *b = t; } int cmp(const void *a, const void *b) {     return *(int *)b - *(int *)a; } int main() {     int t,i,n,sum;     scanf("%d", &t);     while(t--) {         scanf("%d%*c",&n);         sum = 0;         for(i = 0; i < n; i++) {             printf("%d\n", a[i] = get());         }         qsort(a, n, sizeof(int), cmp);         while(--n){             a[n-1] += a[n];             sum += a[n-1];             for(i = n - 1; i > 0; i--){                 if(a[i]<a[i-1])                     break;                 else                     swap(a+i, a+i-1);             }         }         printf("sum = %d\n", sum);     }     return 0; } 只对程序评论，算法建议参考一下网上的。 程序而言，定义过大的数组，作为一个简单的测试程序，你的输入会超过10个吗？那么即使超过10个，那么你能输入100个吗？我估计不会，输入超过10个已经不错了。但是定义了100005，幸好定义了全局变量，不然定义成局部，这样会导致栈的损耗很大，因为栈的空间是有限的，很少的。建议使用大数组，在堆上申请（全局也可以的）。 其他没发现啥问题。 建议c定义成int类型，当然你的使用没啥问题，因为不是和EOF比较。 这个网上就找到一个用堆排序过得 这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 至于不用scanf（“%d”，&n）只是因为之前做过一道用scanf超时的，用字符才能规定时间内完成，就get（）了， [/quote] 你说的超时是那个超时？如果有输入，除非提前写好输入，否则有输入就很容易超时

user: user-0
content: 引用 1 楼 zhao4zhong1 的回复:百度搜“huffman编码” 这个真搜不到 定义已经看了很多了 这道题目一样的只看到一个有用的，看了还是不明白

user: user-0
content: 引用 2 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h> #include <ctype.h>  int c;  int get() {     int num = 0;     while (isdigit(c = getchar())) {         num = num * 10 + c - '0';     }     return num; } int a[105];  void swap(int *a, int *b) {     int t = *a;     *a = *b;     *b = t; } int cmp(const void *a, const void *b) {     return *(int *)b - *(int *)a; } int main() {     int t,i,n,sum;     scanf("%d", &t);     while(t--) {         scanf("%d%*c",&n);         sum = 0;         for(i = 0; i < n; i++) {             printf("%d\n", a[i] = get());         }         qsort(a, n, sizeof(int), cmp);         while(--n){             a[n-1] += a[n];             sum += a[n-1];             for(i = n - 1; i > 0; i--){                 if(a[i]<a[i-1])                     break;                 else                     swap(a+i, a+i-1);             }         }         printf("sum = %d\n", sum);     }     return 0; } 只对程序评论，算法建议参考一下网上的。 程序而言，定义过大的数组，作为一个简单的测试程序，你的输入会超过10个吗？那么即使超过10个，那么你能输入100个吗？我估计不会，输入超过10个已经不错了。但是定义了100005，幸好定义了全局变量，不然定义成局部，这样会导致栈的损耗很大，因为栈的空间是有限的，很少的。建议使用大数组，在堆上申请（全局也可以的）。 其他没发现啥问题。 建议c定义成int类型，当然你的使用没啥问题，因为不是和EOF比较。 这个网上就找到一个用堆排序过得 这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 至于不用scanf（“%d”，&n）只是因为之前做过一道用scanf超时的，用字符才能规定时间内完成，就get（）了，

user: user-0
content: 引用 3 楼 FancyMouse 的回复:50000个1和50000个50001估计就TLE了 这个为什么就不超时了 #include <iostream>   #include <ctime>   using namespace std;      int a[100002];      void swap(int& a, int& b)   {       int temp = a;       a = b;       b = temp;   }      void heapAdjust(int h[], int s, int m)   {       int rc = h[s];       int j;       for(j = 2 *s; j <= m; j *= 2)       {           if(j < m && h[j + 1] < h[j])           {               j ++;           }           if(rc <= h[j])           {               break;           }           h[s] = h[j];           s = j;       }       h[s] = rc;   }      int calc_huff(int h[], int n)   {       int i;       for(i = n / 2; i > 0; i --)       {           heapAdjust(h, i, n);       }       i = n;       int sum = 0;       while(i > 1)       {           swap(h[1], h[i]);           heapAdjust(h, 1, i - 1);           i --;           swap(h[1], h[i]);           heapAdjust(h, 1, i - 1);           sum = sum + h[i] + h[i + 1];           h[i] = h[i] + h[i + 1];       }       return sum;   }      int main()   {       int t;       cin >> t;       while(t --)       {           int n;           cin >> n;           int i;           for(i = 1; i <= n; i ++)           {               cin >> a[i];           }           cout << calc_huff(a, n) << '\n';       }       return 0;   }   堆排序怎么就来的及了 快速排序就算加上引用时间也就不过15ms罢了，不会增加多少的吧

user: user-3
content: 百度搜“huffman编码”

user: user-1
content: 50000个1和50000个50001估计就TLE了

user: user-2
content: #include <stdio.h> #include <stdlib.h> #include <ctype.h>  int c;  int get() {     int num = 0;     while (isdigit(c = getchar())) {         num = num * 10 + c - '0';     }     return num; } int a[105];  void swap(int *a, int *b) {     int t = *a;     *a = *b;     *b = t; } int cmp(const void *a, const void *b) {     return *(int *)b - *(int *)a; } int main() {     int t,i,n,sum;     scanf("%d", &t);     while(t--) {         scanf("%d%*c",&n);         sum = 0;         for(i = 0; i < n; i++) {             printf("%d\n", a[i] = get());         }         qsort(a, n, sizeof(int), cmp);         while(--n){             a[n-1] += a[n];             sum += a[n-1];             for(i = n - 1; i > 0; i--){                 if(a[i]<a[i-1])                     break;                 else                     swap(a+i, a+i-1);             }         }         printf("sum = %d\n", sum);     }     return 0; } 只对程序评论，算法建议参考一下网上的。 程序而言，定义过大的数组，作为一个简单的测试程序，你的输入会超过10个吗？那么即使超过10个，那么你能输入100个吗？我估计不会，输入超过10个已经不错了。但是定义了100005，幸好定义了全局变量，不然定义成局部，这样会导致栈的损耗很大，因为栈的空间是有限的，很少的。建议使用大数组，在堆上申请（全局也可以的）。 其他没发现啥问题。 建议c定义成int类型，当然你的使用没啥问题，因为不是和EOF比较。