问题 J: 简单的变位词
时间限制: 1 Sec 内存限制: 64 MB
提交: 428 解决: 78
[提交][状态][讨论版]
题目描述
变位词是指改变某个词的字母顺序后构成的新词。蔡老板最近沉迷研究变位词并给你扔了一道题:
给你一些单词,让你把里面的变位词分组找出来。互为变位词的归为一组,最后输出含有变位词最多的前五组。如果有组数相同的按照字典序输出。
输入
输入包含由小写字母组成的单词,用换行分割,被EOF终止。 输入数据不超过30000个单词。
输出
输出五组包含单词数量最多的变位词,如果少于五组,输出全部。对每组输出,写出它的大小和成员词,成员词按字典序排序用空格分隔,每组输出之间用换行分隔,相同词只输出一次,但算个数。
样例输入
neuq
tea
bate
beat
caret
trace
nueq
carte
cater
crate
abet
ate
eat
beta
eta
signal
样例输出
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 2: neuq nueq .
Group of size 1: signal .
题解:我们把字符串按照升序排序,这样变位词就变成一个相同的串。用字典树来统计个数,用vector来记录答案。
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<string.h>
#define ll long long
using namespace std;
vector<string>p[30030];
bool cmp(vector<string> a,vector<string> b)
{
if(a.size()==b.size())
{
return a[0]<b[0];
}
else
return a.size()>b.size();
}
string str[30030];
string s[30030];
int trie[25000*20][30];
int val[25000*20];
int cnt=0;
int ge=0;
void insert(string ss,int id)
{
int now=0;
for(int i=0;ss[i];i++)
{
if(0==trie[now][ss[i]-'a']) trie[now][ss[i]-'a']=++cnt;
now=trie[now][ss[i]-'a'];
}
if(0==val[now])val[now]=++ge;
p[val[now]].push_back(str[id]);
}
int main()
{
int tot=0;
while(cin>>str[++tot])
{
s[tot]=str[tot];
sort(s[tot].begin(),s[tot].end());
insert(s[tot],tot);
}
for(int i=1;i<=ge;i++)
{
sort(p[i].begin(),p[i].end());
}
sort(p+1,p+1+ge,cmp);
for(int i=1;i<=5;i++)
{
int op=p[i].size();
if(op==0) break;
cout<<"Group of size "<<op<<":";
cout<<" "<<p[i][0];
for(int j=1;j<op;j++)
{
if(p[i][j]!=p[i][j-1])
cout<<" "<<p[i][j];
} cout<<" ."<<endl;
}
}
也可以将字典树换成map,更简单(原来不会卡map)。
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<map>
#include<vector>
#include<string.h>
#define ll long long
using namespace std;
const int N=1e5+10;
map<string ,int> mp;
vector<string>p[30030];
string str[30030];
string s[30030];
int cnt;
void add(string ss,int id)
{
if(mp.find(ss)==mp.end())
mp[ss]=++cnt;
p[mp[ss]].push_back(str[id]);
}
bool cmp(vector<string> a,vector<string> b)
{
if(a.size()==b.size())
{
return a[0]<b[0];
}
else
return a.size()>b.size();
}
int main()
{
int tot=0;
cnt=0;
while(cin>>str[++tot])
{
s[tot]=str[tot];
sort(s[tot].begin(),s[tot].end());
add(s[tot],tot);
}
for(int i=1;i<=cnt;i++)
{
sort(p[i].begin(),p[i].end());
}
sort(p+1,p+1+cnt,cmp);
for(int i=1;i<=5;i++)
{
int op=p[i].size();
if(op==0) break;
cout<<"Group of size "<<op<<":";
cout<<" "<<p[i][0];
for(int j=1;j<op;j++)
{
if(p[i][j]!=p[i][j-1])
cout<<" "<<p[i][j];
} cout<<" ."<<endl;
}
}