The 16th Zhejiang University Programming Contest - E
来源:互联网 发布:linux下软件安装 编辑:程序博客网 时间:2024/05/21 09:36
Huffman Code is a commonly used optimal prefix code. Here is a simple introduction to Huffman Coding from wikipedia.
The technique works by creating a binary tree of nodes. These can be stored in a regular array, the size of which depends on the number of symbols, S. A node can be either a leaf node or an internal node. Initially, all nodes are leaf nodes, which contain the symbol itself, the weight (frequency of appearance) of the symbol and optionally, a link to a parent node which makes it easy to read the code (in reverse) starting from a leaf node. Internal nodes contain symbol weight, links to two child nodes and the optional link to a parent node. As a common convention, bit '0' represents following the left child and bit '1' represents following the right child. A finished tree has up to n leaf nodes and n-1 internal nodes. A Huffman tree that omits unused symbols produces the most optimal code lengths.
The simplest construction algorithm uses a priority queue where the node with lowest weight is given highest priority:
- Create a leaf node for each symbol and add it to the priority queue.
- While there is more than one node in the queue:
- Remove the two nodes of highest priority (lowest weight) from
the queue- Create a new internal node with these two nodes as children and with weight equal to the sum of the two nodes' weight.
- Add the new node to the queue.
- The remaining node is the root node and the tree is complete.
For example, one day Edward wanted to send a string "aeaaaageqqqq" to his best friend Min as a gift. There are four symbols 'a', 'e', 'g', 'q' and so their weights are 5, 2, 1, 4.
Firstly Edward merged the two symbols 'e' and 'g' with lowest weights and get a node with weight of 1 + 2 = 3. Then Edward merged two nodes of weight 3 and 4 and get a node with weight 3 + 4 = 7. Finally Edward merged the last two nodes. If we distribute the prefix '0' to the smaller node, Edward can get the code of four symbols '0', '101', '100', '11'.
If we know the number of occurrences of each character in some content, can we compress it using Huffman Code and the number of '0's is exactly E? More precisely, let the number of occurrences of the i-th character be Fi and the number of '0's in its huffman code be Ci, we want to know whether there exists a specific huffman code satisfying that the sum of Fi * Ci is equal to E.
Input
There are multiple test cases. The first line of input is an integer T indicates the number of test cases. For each test case:
The first line of each case contains a positive integer S (2 ≤ S ≤ 128), indicates the number of different symbols.
The second line contains exactly S integers Fi (1 ≤ Fi ≤ 1000), indicates the number of occurrence of each symbol.
The third line contains a non-negative integer E (0 ≤ E ≤ 108), indicates the expected number of '0's.
Output
For each case, please output "Yes" if it can be satisfied and "No" in otherwise.
Sample Input
321 3221 3345 2 1 411
Sample Output
NoYesYes
Hint
The possible huffman codes for examples:
- None
- '1', '0'
- '1', '001', '000', '01'
#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <string>#include <cmath>#include <set>#include <queue>#include <algorithm>#include <vector>using namespace std;#define esp 1e-8const double PI = acos(-1.0);const int inf = 1000000005;const long long mod = 1000000007;//freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取//freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中struct number1{ int x; bool operator < (const number1 &a) const { return x>a.x;//最小值优先 }};priority_queue<number1>q; //最小优先级队列int s,e;int num[300];bool dfs(int step,int ans){int temp_1 = ans+num[step*2];int temp_2 = ans+num[step*2+1];step++;if(step==s-1 && (temp_1==e || temp_2==e))return true;else if(step>=s || temp_1>=e || temp_2>=e)return false;else if(dfs(step,temp_1))return true;else if(dfs(step,temp_2))return true;else return false;}int main(){int t,k;number1 f;int ans;scanf("%d",&t);while(t--){scanf("%d",&s);while(!q.empty()) q.pop();for(int i = 0; i < s; i++){scanf("%d",&f.x);q.push(f);}scanf("%d",&e);k = 0; ans= 0;while(q.size() > 1){f.x = 0;f.x+=q.top().x;num[k++] = q.top().x;q.pop();f.x+=q.top().x;num[k++] = q.top().x;q.pop();q.push(f);}if(dfs(0,0))printf("Yes\n");else printf("No\n");}return 0;}
- The 16th Zhejiang University Programming Contest - E
- The 16th Zhejiang University Programming Contest-
- The 12th Zhejiang University Programming Contest
- The 14th Zhejiang University Programming Contest
- The 14th Zhejiang University Programming Contest
- [The 14th Zhejiang University Programming Contest]
- The 15th Zhejiang University Programming Contest
- The 15th Zhejiang University Programming Contest
- The 15th Zhejiang University Programming Contest
- The 15th Zhejiang University Programming Contest
- The 11th Zhejiang University Programming Contest / 解题报告 4.3
- The 11th Zhejiang University Programming Contest - C/ Chinese Zodiac
- The 11th Zhejiang University Programming Contest - G/ Gaussian Prime
- The 11th Zhejiang University Programming Contest C G J
- 115 - The 12th Zhejiang University Programming Contest - C
- The 14th Zhejiang University Programming Contest(未完工)
- 【ZOJ3952 The 17th Zhejiang University Programming Contest E】【简单构造 模拟 or汇编】Fibonacci Sequence Chicken
- The 11th Zhejiang University Programming Contest - J/ Judge Internal Error
- Openstack学习笔记(七)-在Win环境下通过XManager(xshell)远程打开eclipse
- Linux内核分析之七——Linux内核如何装载和启动一个可执行程序
- uva 340 Master-Mind Hints
- 给你日期求那天是星期几
- EasyDarwin安卓直播之EasyPusher NDK开发:JNI回调函数的实现
- The 16th Zhejiang University Programming Contest - E
- Scrapy设置之Downloading media
- TangowithDjango--Start
- 第6周
- Android电子书阅读器的设计与实现
- Mysql安装与配置总结
- java正则表达式
- 关于微信分享接口开发
- __builtins__.str class