1. 程式人生 > >POJ 2408 - Anagram Groups - [字典樹]

POJ 2408 - Anagram Groups - [字典樹]

題目連結:http://poj.org/problem?id=2408

World-renowned Prof. A. N. Agram's current research deals with large anagram groups. He has just found a new application for his theory on the distribution of characters in English language texts. Given such a text, you are to find the largest anagram groups.

A text is a sequence of words. A word w is an anagram of a word v if and only if there is some permutation p of character positions that takes w to v. Then, w and v are in the same anagram group. The size of an anagram group is the number of words in that group. Find the 5 largest anagram groups.

Input
The input contains words composed of lowercase alphabetic characters, separated by whitespace(or new line). It is terminated by EOF. You can assume there will be no more than 30000 words.

Output
Output the 5 largest anagram groups. If there are less than 5 groups, output them all. Sort the groups by decreasing size. Break ties lexicographically by the lexicographical smallest element. For each group output, print its size and its member words. Sort the member words lexicographically and print equal words only once.

Sample Input
undisplayed
trace
tea
singleton
eta
eat
displayed
crate
cater
carte
caret
beta
beat
bate
ate
abet

Sample Output
Group of size 5: caret carte cater crate trace .
Group of size 4: abet bate beat beta .
Group of size 4: ate eat eta tea .
Group of size 1: displayed .
Group of size 1: singleton .

 

題解:

用字典樹把每個組都hash成一個數字 $x$,然後把組內的字串全部存在編號為 $x$ 的vector內。

然後對vector進行排序(實際上是對vector的編號進行排序),再輸出前五項就好了,注意相同的單詞雖然計數,但是輸出時只輸出一次。

 

AC程式碼:

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=3e4+5;
string str;
int idx[maxn];
vector<string> g[maxn];
bool cmp(int i,int j)
{
    if(g[i].size()!=g[j].size())
        return g[i].size()>g[j].size();
    else if(g[i].size() && g[j].size())
        return g[i][0]<g[j][0];
}

namespace Trie
{
    const int SIZE=maxn*2;
    int sz,tot;
    struct TrieNode{
        int ed;
        int nxt[26];
    }trie[SIZE];
    void init(){sz=1, tot=0;}
    int insert(const string& s)
    {
        int p=1;
        for(int i=0;i<s.size();i++)
        {
            int ch=s[i]-'a';
            if(!trie[p].nxt[ch]) trie[p].nxt[ch]=++sz;
            p=trie[p].nxt[ch];
        }
        return trie[p].ed?trie[p].ed:(trie[p].ed=++tot);
    }
};

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    Trie::init();
    while(cin>>str)
    {
        string tmp=str;
        sort(tmp.begin(),tmp.end());
        int t=Trie::insert(tmp);
        g[t].push_back(str);
    }

    for(int i=1;i<=Trie::tot;i++) idx[i]=i;
    sort(idx+1,idx+Trie::tot+1,cmp);

    for(int i=1;i<=5 && g[idx[i]].size()>0;i++)
    {
        vector<string>& v=g[idx[i]];
        cout<<"Group of size "<<v.size()<<": ";
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        for(int k=0;k<v.size();k++) cout<<v[k]<<' ';
        cout<<".\n";
    }
}