CF 1166A Silent Classroom

傳送門
題目大意

n(n100)n \pod{n \le 100} 個學生,我們需要將這些學生分到兩個班上。對於兩名在同一班級的學生,如果他們的名字首字母相同,他們就會聊天。

現在給定這些學生的名字,問最少有多少對學生會在一起聊天。

思路

顯然這些學生的名字並不重要,重要的是這些學生的名字的首字母,因此我們只需要保存以各字母爲首字母的學生數量。

如果兩個學生名字的首字母不同,顯然他們永遠不會對答案有貢獻,因此分開考慮各首字母的同學們。對於一個有 xx 個同學的首字母,設有 yy 名同學分到教室一,有 xyx - y 名同學分到教室二,則這個首字母對答案的貢獻爲:
y(y1)2+(xy)(xy1)2 \frac{y(y - 1)} {2} + \frac {(x - y)(x - y - 1)} {2}

展開得:
y2+(xy)2x2 \frac {y^2 + (x - y)^2 - x} {2}

由均值不等式(的擴展),上式大於等於:
(y+xy2)2x2 (\frac {y + x - y} {2})^2 - \frac {x} {2}
當且僅當 y=xyy = x - y 時等號成立。

所以儘量對分就可以了。

別人的思路

貪心。考慮新來一個人,往首字母相同的人較少的教室走對答案的貢獻小,所以儘量對分就可以了。

考了個高考思維方向都變了(╯‵□′)╯︵┻━┻

參考代碼
n = int(input())
name = [None] * n
for i in range(n):
    name[i] = input()
buf = [0] * 26
for i in range(n):
    buf[ord(name[i][0]) - ord('a')] += 1

ans = 0
for i in range(26):
    part1 = buf[i] // 2
    part2 = buf[i] - part1
    ans += (part1 * (part1 - 1)) // 2 + (part2 * (part2 - 1)) // 2
print(int(ans))
Python 學習筆記

ord 函數獲取一個字符的編碼。

>>> help(ord)
Help on built-in function ord in module builtins:

ord(c, /)
    Return the Unicode code point for a one-character string.

整數除法始終用 //,不然肯定蹦出個浮點數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章