臭道人

2.9

https://pintia.cn/problem-sets/16/problems/671

哈夫曼树

字典树做法:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int n,rc,c,d,num[200],k,flag;
char s[2],t[100];
int trie[10000][2],ind,en[10000];
void build(char *str) {//字典树,前缀树 
    int r = 0,i = 0;
    while(str[i]) {                      
        int e = str[i ++] - '0';
        if(!trie[r][e]) {//A 00000
            trie[r][e] = ++ ind;//B 00001  // ind是当前第几个字符 
        }                //C 0001 
        r = trie[r][e];// D 001    
        if(en[r] == 1) flag = 1;// E 01
        if(str[i]) en[r] = 2;  //F 10
    }                       //G 11
    if(en[r]) flag = 1;
    en[r] = 1;
}
int main() {
    scanf("%d",&n);
    priority_queue<int,vector<int>,greater<int> > q;//升序队列:最小堆 
    for(int i = 0;i < n;i ++) {
        scanf("%s %d",s,&d);
        num[(int)s[0]] = d;//d是出现频率 
        q.push(d);
    }
    while(q.size() > 1) {//利用优先队列计算 权值: 
        d = q.top();
        q.pop();
        d += q.top();
        q.pop();
        q.push(d);//计算原理和  哈夫曼树的计算权值一样. 
        rc += d;
    }//rc是最小权值 
    scanf("%d",&k);//k组判断 
    for(int i = 0;i < k;i ++) {
        c = ind = flag = 0;//初始化 
        memset(trie,0,sizeof(trie));
        memset(en,0,sizeof(en));
        for(int j = 0;j < n;j ++) {
            scanf("%s %s",s,t);
            int len = strlen(t);
            if(len >= n) {flag = 1;break;}//如果长度超出了,就错误了 
            build(t); 
            c += num[int(s[0])] * len;//s[0]是当前该字母,s[1]是读入的空格; //num中存的是出现的次数 
        }
        printf("%s\n",c == rc && !flag ? "Yes" : "No");
    }
}

用sort解法:(数据强度弱的时候可以ac)

#include<bits/stdc++.h>
using namespace std;
int n,k,val;
string str[10010];
map<char,int>m;
bool check()
{
    sort(str,str+n);
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            if(str[j].substr(0,str[i].size())==str[i])    return false;
    return true;
}
int main()
{
    cin>>n;
    priority_queue<int,vector<int>,greater<int>>q;
    for(int i=0;i<n;i++)
    {
        char c;int x;
        cin>>c>>x;
        m[c]=x;    q.push(x);
    }
    while(1)
    {
        int tp=q.top();q.pop();
        if(q.empty())    break;
        tp+=q.top();q.pop();
        q.push(tp);
        val+=tp;
    }
    cin>>k;
    while(k--)
    {
        int len=0,flag=0;
        for(int i=0;i<n;i++)
        {
            char c;
            cin>>c>>str[i];
            len+=m[c]*str[i].size();
            
        }
        if(len==val&&check())    puts("Yes");
        else    puts("No");
    }
}
    
    
View Code

 

posted on 2021-02-09 08:06  臭总  阅读(67)  评论(0编辑  收藏  举报

导航