CCF NOI1136 单词分类

问题链接:CCF NOI1136 单词分类




时间限制: 1000 ms  空间限制: 262144 KB

题目描述 

  Oliver为了学号英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类。
  两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。
  例如“AABAC”,它和“CBAAA”就可以归为一类,而和“AAABB”就不是一类。
  现在Oliver有N个单词,所有单词均由大写字母组成,每个单词的长度不超过100.你要告诉Oliver这些单词会被分成几类。

输入

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

输出

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

样例输入

3
AABAC
CBAAA
AAABB
样例输出

2

数据范围限制

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

提示

 




问题分析

  这个问题可以用排序来解决,需要二次排序,一是单词内排序(按字母排序),二是单词表排序。

  然后数一下有多少单词相同即可

程序说明

  这里同时给出C语言程序和C++语言程序。

  C语言程序和C++语言程序的排序函数不一样,需要注意。

  想比较而言,C++语言的排序函数sort()使用起来比较简洁。

要点详解
  • 使用宏定义可以使得代码可阅读性增强。
  • C语言的排序函数是qsort(),需要留意用法。
  • C++语言的排序函数是sort(),需要留意用法。



参考链接:(略)。

100分通过的C语言程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 10000
#define N2 100

char word[N][N2+1];

int cmp( const void *a , const void *b )
{
    return *(char *)a - *(char *)b;
}

int cmp2(const void * a,const void *b)
{
    return strcmp((char *)a, (char *)b) ; //字典序从小到大
}

int main(void)
{
    int n, len, i;

    scanf("%d", &n);
    for(i=0; i<n; i++) {
        scanf("%s", word[i]);

        len = strlen(word[i]);
        qsort(word[i], len, sizeof(word[i][0]), cmp);
    }

    qsort(word, n, sizeof(word[0]), cmp2);

    int count = n;
    for(i=1; i<n; i++)
        if(strcmp(word[i-1], word[i]) == 0)
            count--;

    printf("%d\n", count);

    return 0;
}


100分通过的C++语言程序:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

const int N = 10000;
string word[N];

int main()
{
    int n;

    cin >> n;
    for(int i=0; i<n; i++) {
        cin >> word[i];

        sort(word[i].begin(), word[i].end());
    }

    sort(word, word + n);

    int count = unique(word, word + n) - word;
    cout << count << endl;

    return 0;
}



posted on 2017-05-03 20:08  海岛Blog  阅读(310)  评论(0编辑  收藏  举报

导航