单词分类(word.c/cpp)
[问题描述]
Oliver为了学好英语决定苦背单词,但很快他发现要直接记住杂乱无章的单词非常困难,他决定对单词进行分类。
两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。
例如“AABAC”,它和“CBAAA”就可以归为一类,而和“AAABB”就不是一类。
现在Oliver有N个单词,所有单词均由大写字母组成,每个单词的长度不超过100。你要告诉Oliver这些单词会被分成几类。
[输入格式]
输入文件的第一行为单词个数N,以下N行每行为一个单词。
[输出格式]
输出文件仅包含一个数,表示这N个单词分成的类数。
[样例输入]
3
AABAC
CBAAA
AAABB
[样例输出]
2
[数据范围]
对于70%的数据满足N≤100。
对于100%的数据满足N≤10000。
==================================
===========================
type
re=array[char]of longint;
var
n:longint;
a:array[1..10000,char]of longint;
st:array[1..10000] of string;
ans:longint;
procedure init;
begin
assign(input,'word.in');
assign(output,'word.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure qsort(s,t:longint);
var
tem_ch:string;
tem:re;
x:string;
i,j:longint;
begin
i:=s; j:=t;
x:=st[(s+t)shr 1];
repeat
while (length(x)<length(st[j]))or((length(x)=length(st[j]))and(x<st[j])) do dec(j);
while (length(st[i])<length(x))or((length(x)=length(st[i]))and(st[i]<x)) do inc(i);
if i<=j then
begin
tem:=a[i]; a[i]:=a[j]; a[j]:=tem;
tem_ch:=st[i]; st[i]:=st[j]; st[j]:=tem_ch;
inc(i); dec(j);
end;
until i>j;
if i<t then qsort(i,t);
if s<j then qsort(s,j);
end;
function pd(t:longint):boolean;
var
i:char;
begin
pd:=true;
for i:='A' to 'Z' do
if a[t,i]<>a[t-1,i] then exit(false);
end;
procedure main;
var
i,j:longint;
ch:char;
begin
readln(n);
fillchar(a,sizeof(a),0);
for i:=1 to n do
begin
while not eoln do
begin
read(ch);
a[i,ch]:=a[i,ch]+1;
end;
readln;
end;
for i:=1 to n do st[i]:='';
for i:=1 to n do
for ch:='A' to 'Z' do
for j:=1 to a[i,ch] do
st[i]:=st[i]+ch;
qsort(1,n);
ans:=1;
for i:=2 to n do
if not pd(i) then inc(ans);
writeln(ans);
end;
begin
init;
main;
terminate;
end.