noip模拟题——单词分类

【问题描述】

Oliver

为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困

难,他决定对单词进行分类。两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。

例如:

“AABAC”,它和“CBAAA”就可以归为一类,而和“AAABB”就不是一类。

现在Oliver有N个单词,所有单词均由大写字母组成,每个单词的长度不超过100.你要告诉Oliver这些单词会被分成几类。

【输入格式】

输入文件的第一行为单词个数N,以下N行每行为一个单词。

【输出格式】

输出文件仅包含一个数,表示这N个单词分成的类数。

【样例输入】

AABAC 

CBAAA 

AAABB 

【样例输出】

【数据范围】

对于70%的数据满足N<=100 

对于100%的数据满足N<=10000

 

开始用的是将26个字母出现的个数统计出来,在乘上26个大质数保存在数组中,最后再扫一遍。(神奇地过了9组):

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a[10000010];
string s1;
int b[30];
int ans=0;
int minn=50000005,maxn=0;
int c[26]={49957,49999,45013,39989,38873,47777,173,211,73,51577,13259,47977,13859,223,4801,38833,3001,1319,222347,13229,10111,3847,46589,15761,43121,1367};
int main()
{
  freopen("word.in","r",stdin);
  freopen("word.out","w",stdout);
  int n;cin>>n;
  for(int j=1;j<=n;j++)
  {
    cin>>s1;
    memset(b,0,sizeof(b));
    int t=s1.size();
    for(int i=0;i<=t-1;i++)
    {
      int q=int(s1[i]);
      if(q<=90)q-=65;
      else q-=97;
      b[q]++;
    }
    int as=0;
    for(int i=0;i<=25;i++)
    {
      as+=b[i]*c[i];
    }
    a[as]++;
    if(as<minn)minn=as;
    if(as>maxn)maxn=as;
  }
  for(int i=minn;i<=maxn;i++)
  if(a[i])ans++;
  cout<<ans;
  return 0;
}

 

后来老师讲了才发现超简单。。。竟然是用集合,直接省去判重了。。。

╮(╯▽╰)╭。。。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
set<string>s1;
string s2;
int n;
using namespace std;
int main()
{
  freopen("word.in","r",stdin);
  freopen("word.out","w",stdout);
  cin>>n;
  for(int i=1;i<=n;i++)
  {
  cin>>s2;
  sort(s2.begin(),s2.end());
  s1.insert(s2);
  }
  cout<<s1.size();
  return 0;
}

godlike~~~

posted @ 2016-10-04 16:58  deadshotz  阅读(551)  评论(0编辑  收藏  举报