在线评测链接
问题描述
塔子哥最近迷上了一个字符串重排的游戏。游戏规则如下:给定一个由小写字母组成的字符串 s s s,通过重新排列 s s s 中的字母,看看最多能组成多少个不同的回文字符串。回文字符串是指一个字符串正着读和反着读完全一样,例如"level"和"noon"都是回文字符串,而"code"不是。
请你帮塔子哥写一个程序,计算给定字符串 s s s 经过重排后最多能组成的不同回文字符串数量。
输入格式
输入一行,包含一个由小写字母组成的字符串 s s s,表示塔子哥手中的初始字符串。
输出格式
输出一个整数,表示字符串 s s s 经过重排后最多能组成的不同回文字符串数量。如果无法组成任何回文字符串,则输出 0 0 0。
样例输入
aabb
样例输出
2
评测数据与规模
-
1 ≤ ∣ s ∣ ≤ 1000 1 \leq |s| \leq 1000 1≤∣s∣≤1000
-
字符串 s s s 只包含小写字母
题解
如果存在两个以上的个数为奇数的字符显然不能构成回文。
对于其他为偶数的情况,因为是回文串,所以我们只需考虑其中半边的情况即可。
现在问题变成了,有 K 种字母,每个字母的个数为 c n t i cnt_i cnti 个,问有多少种情况
假设 K 种字母的和为 n n n
对此我们只需预处理阶层即可 O ( 1 ) O(1) O(1) 计算单个结果,由于涉及到大数运算,这里采用 python 来实现。
AC代码
- Python
from collections import Counter
s = input().strip()
mp = Counter(s)
cnt = 0
v = []
for value in mp.values():
if value % 2 == 1:
cnt += 1
v.append(value // 2)
if cnt > 1:
print(0)
exit(0)
total = sum(v)
f = [1] * (total + 1)
for i in range(1, total + 1):
f[i] = f[i - 1] * i
res = f[total]
for i in v:
res //= f[i]
print(res)