Green Bin(字符串+快排)

时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
We will call a string obtained by arranging the characters contained in a string a in some order, an anagram of a.
For example, greenbin is an anagram of beginner. As seen here, when the same character occurs multiple times, that character must be used that number of times.
Given are N strings s1,s2,…,sN. Each of these strings has a length of 10 and consists of lowercase English characters. Additionally, all of these strings are distinct. Find the number of pairs of integers i,j (1≤i<j≤N) such that si is an anagram of sj.

Constraints
·2≤N≤105
·si is a string of length 10.
·Each character in si is a lowercase English letter.
·s1,s2,…,sN are all distinct.
输入
Input is given from Standard Input in the following format:

N
s1
s2
:
sN

输出
Print the number of pairs of integers i,j (1≤i<j≤N) such that si is an anagram of sj.
样例输入 Copy
【样例1】
3
acornistnt
peanutbomb
constraint
【样例2】
2
oneplustwo
ninemodsix
【样例3】
5
abaaaaaaaa
oneplustwo
aaaaaaaaba
twoplusone
aaaabaaaaa
样例输出 Copy
【样例1】
1
【样例2】
0
【样例3】
4
提示
样例1解释
s1= acornistnt is an anagram of s3= constraint. There are no other pairs i,j such that si is an anagram of sj, so the answer is 1.
样例2解释
If there is no pair i,j such that si is an anagram of sj, print 0.
样例3解释
Note that the answer may not fit into a 32-bit integer type, though we cannot put such a case here.

根据样例和题意,可得题目大意是给定若干个字符串,求有多少对字符串满足字符种类以及数量完全相同。这个题和我昨天写的一个题目单词谜有相似的地方。具体思路就是边输入边对字符串中的字符按字典序升序排序,然后再把字符串构成的数组按字典序升序排序,这样一来,完全相同的字符串就被排在相邻的位置。然后再遍历字符串数组,每求一次连续完全相同的字符串的个数,就应算出对应有多少对。

题目中加粗部分是重点!

几个细节:
1.string类也可以声明数组。
2.判断某一对字符串中字符种类和数量是否完全相同,可以先统一升序排序再比较。
3.说到排序,根据题目给定n的范围(2<=n<=100000),算法的时间复杂度只能是O(nlogn),如果再写O(n2)的排序算法,一定超时。在常见的排序算法中,sort()函数快速排序时间复杂度为O(nlogn),符合要求。
4.说到sort()函数,它的排序范围是前闭后开,因此在对所有字符串进行排序时应该是sort(s,s+n),而不是sort(s,s+n-1)。对单个字符串中的字符排序可以采用sort(s[i].begin(),s[i].end())的形式。
5.根据排列组合知识,n个元素中任选2个,有n*(n-1)/2种选法。
6.统计连续完全相同的字符串的个数时,注意这种情况:从某个位置到数组末尾范围内的字符串都是连续完全相同的,别忘了在循环结束后再累加一次。
7.累加时用long long int型数据。

#include<string>
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
string s[100005];//细节1
int main()
{
    int n;
    int i;
    long long int ans=0;//细节7
    long long int t=1;//细节7
    scanf("%d",&n);
    for(i=0;i<=n-1;i++)
    {
        cin>>s[i];
        sort(s[i].begin(),s[i].end());//细节2,3,4
    }
    sort(s,s+n);//细节4
    for(i=0;i<=n-2;i++)
    {
        if(s[i]==s[i+1])t++;//统计某一段连续完全相同的字符串的个数
        else
        {
            ans+=t*(t-1)/2;//细节5
            t=1;
        }
    }
    ans+=t*(t-1)/2;//细节6,7
    printf("%lld",ans);//细节7
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值