ZOJ Problem Set - 1038 T9

中等難度的字典樹。

用到的是DFS+優先隊列的方法。比較容易實現,但是效率不太高~  10ms。(cin,cout);

首先,插入,每個節點要其記錄權值。然後DFS每個點,push入隊列,對<的重載也很容易寫。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <limits.h>
#include <queue>
#include <stack>
using namespace std;
string a[11];
struct trie
{
    int p;
    trie*  next[26];
};
struct word
{
    string s;
    int pri;
};
priority_queue<word> q;
string que;
int len;
void inst(trie* root,string s,int pp)
{
    int i = 0;
    trie* p = root;
    int len = s.size();
    while(i < len)
    {
        int  k = s[i]-'a';
        if(p->next[k] == NULL)
        {
            trie* tmp = new trie;
            for(int j = 0;j < 26;j ++)
            tmp->next[j] = NULL;
            tmp->p = pp;
            p->next[k] = tmp;
        }
        else
        {
            p->next[k]->p += pp;
        }
        p = p->next[k];
        i ++;
    }
}

void dfs(int id,trie *r,string ss)
{
    int i,j,l;
    string sss;
    for(i = id;i < len-1&&i < id+1; i ++)
    {
        if(que[i]!='7'&&que[i]!='9')
        l = 3;
        else l = 4;
        for(j = 0;j < l;j ++)
        {
            int k = a[que[i]-'0'][j] - 'a';
            //cout<<k<<endl;
            if(r->next[k]!=NULL)
            {
                word tmp;
                sss = ss;
                sss += char(k +'a');
                //cout<<sss<<" "<<k<<endl;
                tmp.s = sss;
                tmp.pri = r->next[k]->p;
                q.push(tmp);
                dfs(i+1,r->next[k],sss);
            }
        }
    }
}
bool operator < (const word &a,const word &b)
{
    if(a.s.size() != b.s.size()) return a.s.size() > b.s.size();
    else if(a.pri!=b.pri) return a.pri < b.pri;
    else return a.s > b.s;
}
int main()
{
    a[2]="abc";a[3]="def";a[4]="ghi";
    a[5]="jkl";a[6]="mno";a[7]="pqrs";
    a[8]="tuv";a[9]="wxyz";
    int t,w,m,i;
    string str;
    cin>>t;
    trie *root = new trie;
    int tt = 0;
    while(t --)
    {
        for(i = 0;i < 26;i ++)
        root->next[i] = NULL;
        root->p = 0;
        cin>>w;
        for(i = 0;i < w;i ++)
        {
            cin>>str>>m;
            inst(root,str,m);
        }
        cin>>w;
        cout<<"Scenario #"<<++tt<<":"<<endl;
        for(i = 0 ;i < w;i ++)
        {
            cin>>que;
            len = que.size();
            dfs(0,root,"");
            for(int j = 0;j < len-1;j ++)
            {
                if(!q.empty()){
                cout<<q.top().s<<endl;
                while(!q.empty())
                {
                    if(q.top().s.size()==j+1) q.pop();
                    else break;
                }
                }
                else cout<<"MANUALLY"<<endl;
            }
            cout<<endl;
        }
        cout<<endl;
    }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章