题目链接
输入:
第一行为出现的字符数N,
第二行为N个字符及其出现频率的交替,
第三行为同学数
之后为N个同学在第二行的内容下提交的霍夫曼编码,
输出:
针对每个同学的答案,判断对错,输出"Yes"or"No"
样例:
思路:
要判断1个同学的答案对不对,就要判断:
1、这个同学的答案树的编码长度是否等于最优值
2、这个同学的答案树中是否有前缀码存在
此题要解决的主要子问题有
1、根据第二行输入,自己找出最小编码长度(WPL)
2、计算同学答案树的编码长度,并与我们的答案比较
3、检查同学的答案树中是否有前缀码
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <queue>
#include <string>
#define MAX 70
using namespace std;
int N,codelen;
struct Code
{
int frequency;
string s;
char data;
}array[MAX];
struct TreeNode
{
int frequency;
char data;
struct TreeNode *Left;
struct TreeNode *Right;
};
typedef struct TreeNode* Tree;
int WPL(priority_queue<int,vector<int>,greater<int> > h)
{
int wpl=0;
while(h.size()>1){
int t1=h.top();
h.pop();
int t2=h.top();
h.pop();
wpl+=(t1+t2);
h.push(t1+t2);
}
//不用权值乘以路径长度,每上升一层就加一次权值,
//同样实现了倍乘,@余cos大佬牛逼
return wpl;
}
bool check()
{//检测前缀码
Tree head=(Tree)malloc(sizeof(struct TreeNode));
head->frequency=0;
head->Left=0;
head->Right=0;
for(int i=0;i<N;++i)
{
Tree tmp=head;
for(int j=0;j<array[i].s.length();j++)
{
if(array[i].s[j]=='0')
{
if(!tmp->Left)
{
tmp->Left=(Tree)malloc(sizeof(struct TreeNode));
tmp=tmp->Left;
tmp->frequency=0;
tmp->Left=0;
tmp->Right=0;
}
else{
tmp=tmp->Left;
}
if(tmp->frequency!=0)
{
return 0;
}
}
else if(array[i].s[j]=='1')
{
if(!tmp->Right)
{
tmp->Right=(Tree)malloc(sizeof(struct TreeNode));
tmp=tmp->Right;
tmp->frequency=0;
tmp->Left=0;
tmp->Right=0;
}
else{
tmp=tmp->Right;
}
if(tmp->frequency!=0)
{
return 0;
}
}
}
if(tmp->Left||tmp->Right)
{
return 0;
}
tmp->data=array[i].data;
tmp->frequency=array[i].frequency;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);
//减少C++读入数据的时间,算法比赛可能用
cin>>N;
priority_queue<int,vector<int>,greater<int> > heap;//堆
for(int i=0;i<N;i++)
{
cin>>array[i].data>>array[i].frequency;
heap.push(array[i].frequency);
}
codelen=WPL(heap);
int M;
cin>>M;
while(M--)
{
int len=0;
for(int i=0;i<N;i++)
{
cin>>array[i].data>>array[i].s;
len+=array[i].frequency*array[i].s.length();
}
if(len==codelen && check())cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}