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";
    }
}

原文地址:https://www.cnblogs.com/dilthey/p/9986550.html

时间: 2024-10-31 08:50:53

POJ 2408 - Anagram Groups - [字典树]的相关文章

poj 2408 Anagram Groups(hash)

题目链接:poj 2408 Anagram Groups 题目大意:给定若干个字符串,将其分组,按照组成元素相同为一组,输出数量最多的前5组,每组按照字典序输出所 有字符串.数量相同的输出字典序较小的一组. 解题思路:将所有的字符串统计字符后hash,排序之后确定每组的个数并且确定一组中字典序最小的字符串.根据个数 以及字符串对组进行排序. #include <cstdio> #include <cstring> #include <vector> #include &

poj 2408 Anagram Groups

Description 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 la

POJ 2408 Anagram Groups 排序到极致

Anagram Groups Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4903   Accepted: 1316 Description 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 t

poj 2503:Babelfish(字典树,经典题,字典翻译)

Babelfish Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 30816   Accepted: 13283 Description You have just moved from Waterloo to a big city. The people here speak an incomprehensible dialect of a foreign language. Fortunately, you have

poj 3630 Phone List (字典树 +静态字典树)

Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22235   Accepted: 6885 Description Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogu

POJ训练计划_Colored Sticks(字典树+判断欧拉通路)

解题报告 http://blog.csdn.net/juncoder/article/details/38236333 题目传送门 题意: 问给定一堆的棒,两端有颜色,相同的颜色的棒可以头尾相接,能否连在一条直线. 思路: 把每一根棒两端看成两个点,之间连着线,判断这样的一个图中是否有欧拉通路 欧拉通路: 在联通无向图中,经过G的每一条边一次并且仅有一次的路径为欧拉通路. 求欧拉通路的充分条件:图为联通图,并且仅有两个奇度数的结点或无奇度结点. #include <queue> #includ

POJ 2513 Colored Sticks(字典树+并查集连通性+欧拉回路)

题目地址:POJ 2513 刚开始没想到字典树,用的map函数一直TLE,由于上一次的签到题由于没想到字典树而卡了好长时间的深刻教训,于是过了不久就想起来用字典树了,(为什么是在TLE了5次之后..T^T)然后把map改成了字典树,然后就过了. 这题居然不知不觉的用上了欧拉回路..其实当时我是这样想的..因为相互接触的必须要相同,所以除了两端外,其他的都是两两相同的,所以除了两端的颜色外其他的的个数必须为偶数.然后两端的可能相同可能不相同,相同的话,说明所有的都是偶数个数了,不相同的话那就只有这

POJ 2503 Babelfish(字典树)

题目链接:http://poj.org/problem?id=2503 题意:翻译单词,若在词典中找不到则输出eh. 思路:裸的字典树. 代码: #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <string> #include <vector> using

poj 1204 Word Puzzles(字典树)

题目链接:http://poj.org/problem?id=1204 思路分析:由于题目数据较弱,使用暴力搜索:对于所有查找的单词建立一棵字典树,在图中的每个坐标,往8个方向搜索查找即可: 需要注意的是查找时不能匹配了一个单词就不在继续往该方向查找,因为在某个坐标的某个方向上可能会匹配多个单词,所以需要一直 查找直到查找到该方向上最后一个坐标: 代码如下: #include <cstdio> #include <cstring> #include <iostream>