In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.
Input Specification:
Each input file contains one test case. For each case, the first line gives an integer N (2 <= N <= 63), then followed by a line that contains all the N distinct characters and their frequencies in the following format:
c[1] f[1] c[2] f[2] ... c[N] f[N]
where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (<=1000), then followed by M student submissions. Each student submission consists of N lines, each in the format:
c[i] code[i]
where c[i] is the i-th character and code[i] is a string of '0's and '1's.
Output Specification:
For each test case, print in each line either “Yes” if the student’s submission is correct, or “No” if not.
Sample Input:7 A 1 B 1 C 1 D 3 E 3 F 6 G 6 4 A 00000 B 00001 C 0001 D 001 E 01 F 10 G 11 A 01010 B 01011 C 0100 D 011 E 10 F 11 G 00 A 000 B 001 C 010 D 011 E 100 F 101 G 110 A 00000 B 00001 C 0001 D 001 E 00 F 10 G 11Sample Output:
Yes Yes No No
/* 因为有赫夫曼编码可知WPL有且只有一个最小值 虽然赫夫曼树可以有多个 还有一个条件是 短码不能是长码的前缀*/ #include <iostream> #include <algorithm> #include <string> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include<queue> #include<stack> #include<map> #include<set> using namespace std; #define lson rt<<1,l,MID #define rson rt<<1|1,MID+1,r //#define lson root<<1 //#define rson root<<1|1 #define MID ((l+r)>>1) typedef long long ll; typedef pair<int,int> P; const int maxn=100; const int base=1000; const int inf=999999; const double eps=1e-5; struct tt { char op; int num; }a[maxn]; struct kk { char op; string s; }b[maxn]; bool cmp(kk a,kk b) { return a.s.size()<b.s.size(); } bool pan(int n)// 判断是否有短码构成了 长码的前缀码 { sort(b,b+n,cmp); for(int i=0;i<n;i++) { string tmp=b[i].s; for(int j=i+1;j<n;j++) { if(b[j].s.substr(0,tmp.size())==tmp) return false; } } return true; } int pos(char op,int n)// 返回 同学提交的字符 在原来的的字符中的位置 防止顺序不一致的出现 { for(int i=0;i<n;i++) if(a[i].op==op)return i; //printf("---------------------------\n"); } int main() { int n,m,i,j,k,t; cin>>n; priority_queue<int,vector<int>,greater<int> > q; for(i=0;i<n;i++) { cin>>a[i].op>>a[i].num; q.push(a[i].num); } int wpl=0;//先找到按赫夫曼编码的WPL while(!q.empty()) { int a,b; a=q.top();q.pop(); if(!q.empty()){b=q.top();q.pop();q.push(a+b);}//弹出是没有判断 是否为空 pat提示 异常退出 错了8次 m=a+b; wpl+=m; } wpl-=m; //cout<<wpl<<endl; cin>>m; while(m--) { int wpl2=0;// 计算该同学的WPL2 和 WPL 比较 for(i=0;i<n;i++) { cin>>b[i].op>>b[i].s; wpl2+=a[pos(b[i].op,n)].num*b[i].s.size(); } if(wpl2>wpl) { puts("No"); } else if(!pan(n)) { puts("No"); } else { puts("Yes"); } } return 0; }