Description
Pushok the dog has been chasing Imp for a few hours already.
Fortunately, Imp knows that Pushok is afraid of a robot vacuum cleaner.
While moving, the robot generates a string t consisting of letters ‘s’ and ‘h’, that produces a lot of noise. We define noise of string t as the number of occurrences of string “sh” as a subsequence in it, in other words, the number of such pairs
(i, j)
, that
i
<
The robot is off at the moment. Imp knows that it has a sequence of strings ti in its memory, and he can arbitrary change their order. When the robot is started, it generates the string t as a concatenation of these strings in the given order. The noise of the resulting string equals the noise of this concatenation.
Help Imp to find the maximum noise he can achieve by changing the order of the strings.
Input
The first line contains a single integer n (1 ≤
Next n lines contain the strings t1, t2, ..., tn , one per line. It is guaranteed that the strings are non-empty, contain only English letters ‘s’ and ‘h’ and their total length does not exceed 10 5 .
Output
Print a single integer — the maxumum possible noise Imp can achieve by changing the order of the strings.
Examples
Input |
---|
4 ssh hs s hhhs |
Output |
18 |
Input |
---|
2 h s |
Output |
1 |
Note
The optimal concatenation in the first sample is ssshhshhhs.
题意:给n个只包含‘s’和‘h’的字符串,调整他们的顺序,使拼起来的串含有最多的以‘s’开头以‘h’结尾的字串。
思路:首先考虑子串数目的计算对于两个字符串
t1
和
t2
。对于每个给定的字符串,其内部顺序是不可以改变的,因此记录它含有的s,h,和内部sh字串的数目就已经包含计算子串所需要的全部信息了,不妨抽象为一个数据结构
struct{
int cnts;//含有的s数量
int cnth;//含有的h数量
int ns;//内部sh子串数量
};
容易计算出连接 t1 - t2 形成的串有的子串数量为 t1 .ns + t2 .ns + t1 .cnts × t2 .cnth。在寻找最大子串数量的过程中, t1 .ns 和 t2 .ns无论怎么摆放都不变,调整顺序只改变了用哪些字符串的cnts来乘哪些字符串的cnth,因此可以给这个数据结构定义一个先后关系,如果 t1 .cnts × t2 .cnth > t2 .cnts × t1 .cnth ,那么就认为 t1 应该排在 t2 前面,如果两个乘积相同,就应该把含‘s’更多的字符串放在前面。有了这个关系,就可以用sort函数来排序啦,最后的计算也比较容易,应该注意到一点是,s和h的数量可以达到几万,相乘的结果用int保存可能会溢出。
#include <stdio.h>
#include<algorithm>
using std::sort;
struct sh
{
unsigned long cnts;
unsigned long cnth;
int ns;
sh():cnts(0),cnth(0),ns(0) {}
}str[100005];
bool cmp(sh a, sh b) {
unsigned long tempa = a.cnts*b.cnth;//用unsigned long 暂存结果
unsigned long tempb = a.cnth*b.cnts;
if (tempa >tempb)return true;
else if (tempa < tempb)return false;
else {//“相等”的情况
//把含's'更多的字符串放在前面,能与其他字符串生成更多的sh子串
if (a.cnts > b.cnts)
return true;
if (a.cnts < b.cnts)return false;
else {
return a.cnth < b.cnth;
}
}
}
char d;
int main() {
int n;
long long ans=0, ts=0, th=0;
scanf("%d", &n);
scanf("%c", &d);//额外的换行符
for (int i = 0; i < n;++i) {
while (1)
{
scanf("%c", &d);
if (d == 's')str[i].cnts++;
else if (d == 'h') { str[i].cnth++; str[i].ns += str[i].cnts; }
else break;//读取到回车,一个输入结束
}
}
sort(str, str + n, cmp);//按我们定义的先后关系排序
//最后的计算,用ts记录当前位置前面已经有多少个s
for (int i = 0; i < n; ++i) {
//加上这个字符串的内部sh子串数
ans += str[i].ns;
//这个字符串与前面的所有的字符串产生sh子串数
ans += ts*str[i].cnth;
//更新ts
ts += str[i].cnts;
}
printf("%I64d\n", ans);
}