Problem:
 Score : 100 points    Problem Statement   Kyoto University Programming Contest is a programming contest voluntarily held by some Kyoto University students.
		                This contest is abbreviated as K yoto U niversity P rogramming C ontest and called KUPC.  source: Kyoto University Programming Contest Information    The problem-preparing committee met to hold this year's KUPC and N problems were proposed there.
		            The problems are numbered from 1 to N and the name of i -th problem is P_i .
		            However, since they proposed too many problems, they decided to divide them into some sets for several contests.  They decided to divide this year's KUPC into several KUPCs by dividing problems under the following conditions.  One KUPC provides K problems.  Each problem appears at most once among all the KUPCs.  All the first letters of the problem names in one KUPC must be different.    You, one of the committee members, want to hold as many KUPCs as possible.
		            Write a program to find the maximum number of KUPCs that can be held this year.  Constraints    1 \leq N \leq 10^4   1 \leq K \leq 26   1 \leq |P_i| \leq 10  All characters in P_i are capital letters.   Note that, for each i and j  (1 \leq i < j \leq N) , P_i \neq P_j are not necessarily satisfied.        Input  The input is given from Standard Input in the following format:   N  K  P_1 : P_N       Output  Print the maximum number of KUPCs that can be held on one line.        Sample Input 1  9 3
APPLE
ANT
ATCODER
BLOCK
BULL
BOSS
CAT
DOG
EGG  For example, three KUPCs can be held by dividing the problems as follows.   First: APPLE , BLOCK , CAT  Second: ANT , BULL , DOG  Third: ATCODER , BOSS , EGG       Sample Output 1  3      Sample Input 2  3 2
KU
KYOUDAI
KYOTOUNIV      Sample Output 2  0  No KUPC can be held.

Solution (Python):
from collections import Counter

N,K=map(int,input().split())
P = [input() for _ in range(N)]

c = Counter([P[i][0] for i in range(N)])

ans = 0
while True:
  mc = c.most_common()
  if len(mc)<K:break
  if mc[K-1][1] == 0: break
  mc = mc[:K]
  for k,v in mc:
    c[k] -= 1
  ans += 1
  
print(ans)

Solution (Python):
import collections 
n,k=map(int,input().split())
p=[str(input()) for _ in range(n)]
for i in range(n):
    p[i]=p[i][0:1]

c=collections.Counter(p)

a=[]
for v in c.values():
    a.append(v)

a.sort(reverse=True)
ans=0



while True:
    a.sort(reverse=True)
    if k<=len(a):
        ans+=1
        for i in range(k):
            a[i]-=1
        for i in range(k-1,-1,-1):
            
            if a[i]==0:
                a.pop(i)
        
    else:
        break

print(ans)

Solution (Python):
n,k = map(int,input().split())
p = [input()[0] for i in range(n)]
from collections import Counter
c = Counter(p)
v = sorted(list(c.values()),reverse=True)
ans = 0
while len(v)>=k:
    for i in range(k):
        v[i] -= 1
        if v[i]<0:
            print(ans)
            exit()
    ans += 1
    v = sorted(v,reverse=True)
print(ans)

Solution (Python):
n,k = map(int, input().split())
word = [0 for i in range(26)]
ans = 0
for i in range(n):
    q = input()
    word[ord(q[0]) - ord('A')] += 1
word.sort(reverse=True)
for i in range(n//k):
    for j in range(k):
        word[j] -= 1
        if word[j] < 0:
            print(ans)
            exit()
    ans += 1
    word.sort(reverse=True)
print(ans)

Solution (Python):
from collections import Counter
n, k = map(int, input().split())
P = [input()[0] for _ in range(n)]
CP = Counter(P)

P = list(CP.values())
ans = 0
while len(P) >= k:
  P.sort(reverse=True)
  for i in range(k):
    P[i] -= 1
  P = [i for i in P if i > 0]
  ans += 1
print(ans)

Solution (Python):
import sys
N,K = list(map(int, input().split(' ')))
d = {}
for i in range(N):
    S = str(input())[0]
    if S in d:
        d[S] += 1
    else:
        d[S] = 1
p = list(d.values())
if len(p) < K:
    print(0)
    sys.exit()
c = 0
while(len(p) >= K):
    c += 1
    sq = sorted(p, reverse=True)
    for i in range(K):
        sq[i] = sq[i] - 1
    p = [i for i in sq if i != 0]
print(c)

Solution (Python):
from heapq import *
n,k=map(int,input().split())
s=[0]*26
for i in range(n):
    s[ord(input()[0])-65]-=1
s=[i for i in s if i<0]
d=0
while len(s)>=k:
    t=[]
    for i in range(k):
        a=heappop(s)
        if a+1!=0:
            t.append(a+1)
    for j in t:
        heappush(s,j)
    d+=1
print(d)

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

from collections import Counter
import numpy as np

N,K = map(int,input().split())
P = [input().rstrip()[0] for _ in range(N)]

counter = np.array(tuple(Counter(P).values()))

answer = 0
while True:
    counter.sort()
    counter = counter[::-1]
    counter = counter[counter>0]
    if len(counter) < K:
        break
    counter[:K] -= 1
    answer += 1

print(answer)

Solution (Python):

from collections import defaultdict

def main():
    num, k = map(int, input().split())
    data = [input() for i in range(num)]
    initial_dic = defaultdict(int)
    for i in range(num):
        initial_dic[data[i][0]] += 1

    aaa = list(initial_dic.values())
    aaa.sort(reverse=True)
    ans = 0
    if len(aaa) < k:
        pass
    else:
        while 1:
            if aaa[k - 1] == 0:
                break
            for i in range(k):
                aaa[i] -= 1
            ans += 1
            aaa.sort(reverse=True)

    print(ans)




if __name__ == '__main__':
    main()

Solution (Python):
def inpl(): return list(map(int, input().split()))

N, K = inpl()
S = [0]*26
for _ in range(N):
    S[ord(input()[0]) - 65] += 1

ans = 0
while True:
    S = sorted(S, reverse=True)
    s = S[K-1]
    if s == 0:
        break
    ans += 1
    for i in range(K):
        S[i] -= 1
print(ans)

Solution (Python):
n,k = map(int,input().split())
p = [input() for _ in range(n)]
p_ini = [0]*26
for _p in p:
    p_ini[ord(_p[0])-ord('A')] += 1
res = 0
while p_ini.count(0)<=26-k:
    p_ini = sorted(p_ini)[::-1]
    for i in range(k):
        if p_ini[i]!=0:
            p_ini[i] -= 1
    res += 1
print(res)

Solution (Python):
from collections import Counter
from heapq import heappop,heappush
n,k = (int(i) for i in input().split())
p = [input()[0] for i in range(n)]
c,h,ans = Counter(p),[],0
for i,j in c.most_common(): heappush(h,-j)
while len(h)>=k:
	x,ans = [],ans+1
	for i in range(k):
		m = heappop(h)
		if m+1<0: x.append(m+1)
	for i in x: heappush(h,i)
print(ans)

Solution (Python):
import heapq
N,K = map(int,input().split())
hist = [0] * 26

def ctoi(c):
    return ord(c) - ord('A')

for i in range(N):
    c = input()[0]
    hist[ctoi(c)] -= 1

if K == 1:
    print(N)
    exit()
if K == 26:
    print(min(hist))
    exit()

heapq.heapify(hist)
ans = 0
while True:
    used = []
    for i in range(K):
        a = heapq.heappop(hist)
        if a == 0:
            print(ans)
            exit()
        used.append(a+1)
    ans += 1
    for u in used:
        heapq.heappush(hist, u)

Solution (Python):
n,K=[int(x) for x in input().split()]
ans=0
from collections import defaultdict
d=defaultdict(int)
for i in [0]*n:
    d[input()[0]]+=1
while True:
    for j,_ in zip(sorted(d.items(),key=lambda x:x[1],reverse=True),[0]*K):
        k,v=j
        if v==0 or len(d)<K:
            print(ans//K)
            import sys
            sys.exit()
        ans+=1
        d[k]-=1

Solution (Python):
import sys
N,K = list(map(int, input().split(' ')))
d = {}
for i in range(N):
    S = str(input())[0]
    if S in d:
        d[S] += 1
    else:
        d[S] = 1
p = list(d.values())
if len(p) < K:
    print(0)
    sys.exit()
c = 0
while(len(p) >= K):
    c += 1
    sq = sorted(p, reverse=True)
    for i in range(K):
        sq[i] = sq[i] - 1
    p = [i for i in sq if i != 0]
print(c)

Solution (Python):
import sys
n, k = [int(x) for x in sys.stdin.readline().split()]
p = [x.strip()[0] for x in sys.stdin.read().split()]
if len(set(p)) < k:
	print 0
	exit()
dic = {}
for x in p:
	dic[x] = dic.get(x, 0) + 1
loop, count = True, 0
while(loop):
	ctr, inc = k, False
	for x, _ in sorted(dic.items(), key=lambda x: x[1], reverse=True):
		if ctr == 0:
			count += 1
			inc = True
			break
		if dic[x] <= 0:
			loop = False
			break
		else:
			dic[x] -= 1
		ctr -= 1
	if ctr != 0:
		loop = False
	elif not inc:
		count += 1
print count

Solution (Python):
n,k=map(int,input().split())
p = [0]*26
for _ in range(n):
    s = input()
    p[ord(s[0])-ord('A')] += 1
p = list(sorted(p, reverse=True))
ans = 0
while p[0] > 0:
    for i in range(k):
        p[i] -= 1
    p = list(sorted(p, reverse=True))
    if p[25] < 0:
        break
    ans += 1
print(ans)

Solution (Python):
def main():
    n, k = [int(x) for x in input().split()]
    letters = []
    for _ in range(n):
        letters.append(input()[0])
    alphabet = [0 for _ in range(26)]
    for letter in letters:
        alphabet[ord(letter) - 65] += 1
    alphabet.sort(reverse=True)
    num_contests = 0
    picked = 0
    idx = 0
    while idx < 26:
        if alphabet[idx] > 0:
            picked += 1
            alphabet[idx] -= 1
        if picked == k:
            num_contests += 1
            picked = 0
            idx = -1
            alphabet.sort(reverse=True)
        idx += 1
    print(num_contests)


if __name__ == "__main__":
    main()

Solution (Python):
temp=[int(i) for i in input().split()]
N=temp[0]
K=temp[1]
P=[input()[0] for i in range(N)]

alpha=[0 for i in range(26)]
for i in P:
	alpha[ord(i)-65]+=1

ans=0
while True:
	alpha.sort()
	alpha.reverse()
	for i in range(K):
		if alpha[i]>0:
			alpha[i]-=1
		else:
			break
	else:
		ans+=1
		continue
	break
print(ans)

Solution (Python):
N, K = map(int, input().split())
L = [0 for i in range(26)]
for i in range(N):
    p = input()
    L[ord(p[0]) - ord("A")] += 1
ans = 0
while True:
    maxv = [0 for k in range(K)]
    argmax = [-1 for k in range(K)]
    cnt = 0
    for n in range(26):
        minimum = min(maxv)
        if L[n] > minimum:
            for k in range(K):
                if maxv[k] == minimum:
                    argmax[k] = n
                    maxv[k] = L[n]
                    break
    
    if 0 in maxv:
        print(ans)
        break
    else:
        for k in range(K):
            L[argmax[k]] -= 1
        ans += 1

Solution (Python):
n,k=map(int,raw_input().split())
c=[0]*200
for i in[0]*n:c[ord(raw_input()[0])]+=1
p=a=0
while p<1:
 c.sort();p=k;a+=1
 for i in range(k+1):p-=c[-i]>0;c[-i]-=1
print a-1

Solution (Python):

from collections import defaultdict
from heapq import *
import sys
d=defaultdict(int)
n,k=map(int,sys.stdin.readline().split())
for _ in range(n):
	s=sys.stdin.readline().strip()
	d[s[0]]-=1
if len(d)<k:
	print(0)
else:
	q=[]
	for khi in d:
		heappush(q,[d[khi],khi])
	r=0
	while 1:
		a=[heappop(q) for _ in range(k)]
		if any(e[0]==0 for e in a): break
		for e in a:
			e[0]+=1
			heappush(q,e)
		r+=1
	print(r)

Solution (Python):

from collections import defaultdict
from heapq import *
import sys
d=defaultdict(int)
n,k=map(int,sys.stdin.readline().split())
for _ in range(n):
	s=sys.stdin.readline().strip()
	d[s[0]]-=1
if len(d)<k:
	print(0)
else:
	q=[]
	for khi in d:
		heappush(q,[d[khi],khi])
	r=0
	while 1:
		a=[heappop(q) for _ in range(k)]
		if any(e[0]==0 for e in a): break
		for e in a:
			e[0]+=1
			heappush(q,e)
		r+=1
	print(r)

Solution (Python):
import collections
import itertools
n, k = map(int, input().split())
c = collections.Counter(input()[0] for _ in range(n))
for r in itertools.count(0):
    if len(c) < k:
        print(r)
        break
    c2 = collections.Counter(x for x, n in c.most_common(k))
    c -= c2

Solution (Python):
from collections import defaultdict
n,k=map(int,input().split())
dd=defaultdict(int)
for i in range(n):
    p=input()[0]
    dd[p]+=1
ans=0
while True:
    tmp_arr = sorted(dd.items(), key=lambda x: x[1], reverse=True)
    if len(tmp_arr)<k or tmp_arr[k-1][1]==0:
        break
    else:
        for i in range(k):
            dd[tmp_arr[i][0]]-=1
        ans+=1
print(ans)

Solution (Python):
def read():
    return int(input())

def reads(sep=None):
    return list(map(int, input().split(sep)))

def main():
    n, k = reads()
    d = dict()
    for _ in range(n):
        p = input()[0]
        if p not in d: d[p] = 0
        d[p] += 1
    l = [list(item) for item in d.items()]
    c = 0
    while k <= len(l):
        l = sorted(l, key=lambda x:x[1], reverse=True)
        for i in range(k):
            l[i][1] -= 1
        l = [x for x in l if x[1]]
        c += 1
    print(c)

main()

Solution (Python):
N,K = map(int, raw_input().split())
dic = {}
for _ in xrange(N):
  p = raw_input()
  if p[0] in dic:
    dic[p[0]] += 1
  else:
    dic[p[0]] = 1

counter = 0
while True:
  tmp = sorted(dic.items(), key=lambda x:x[1], reverse=True)
  if len(dic) < K: break
  for i in xrange(K):
    dic[tmp[i][0]] -= 1
    if dic[tmp[i][0]] == 0:
      del dic[tmp[i][0]]
  counter += 1

print counter

Solution (Python):
from collections import defaultdict

if __name__ == '__main__':
    n, k = [int(x) for x in input().split()]
    p = []
    p_dict = defaultdict(list)
    ans = 0
    stop = False
    for i in range(n):
        p.append(str(input()))
    for prob in p:
        p_dict[prob[0]].append(prob)
    while True:
        cnt = 0
        more_to_go = False
        sorted_dict = sorted(p_dict, key=lambda x: len(p_dict[x]), reverse=True)
        for key in sorted_dict:
            if p_dict[key]:
                p_dict[key].pop()
                cnt += 1
                if cnt == k:
                    ans += 1
                    more_to_go = True
                    break
        if not more_to_go:
            break
    print(ans)

Solution (Python):
import numpy as np
C_vec = np.zeros(26)
N, K = map(int, raw_input().split())

for i in range(N):
    C_vec[ord((raw_input()[0])) - ord('A')] += 1


while True:
    m = int(C_vec.sum() / K)
    C_vec = np.minimum(C_vec, m)
    m_next = int(C_vec.sum() / K)
    if m_next == m:
        break
    else:
        m = m_next

print m

Solution (Python):
def calc(ls, k):
    cnt = 0
    while ls[0] > 0:
        ls.sort(reverse=True)
        for i in range(k):
            ls[i] -= 1
            if ls[i] < 0:
                return cnt
        ls.sort(reverse=True)
        
        cnt += 1
    return cnt

n, k = map(int, input().split())
ls = [0 for i in range(26)]
for i in range(n):
    word = input()
    inx = ord(word[0]) - ord('A')
    ls[inx] += 1
ls.sort(reverse=True)
ans = calc(ls, k)
print(ans)

Solution (Python):

import sys,copy,math,heapq,itertools as it,fractions,re,bisect,collections as coll

N, K = map(int, raw_input().split())
P = set([raw_input() for i in xrange(N)])

cnt = [0]*26
for p in P:
    cnt[ord(p[0]) - ord("A")] += 1

ans = 0
while 1:
    cnt.sort(reverse = True)
    k = 0
    for i in xrange(26):
        if cnt[i] > 0:
            k += 1
            cnt[i] -= 1
        if k == K:
            ans += 1
            break
    else:
        break
print ans

Solution (Python):
N, K = [int(x) for x in input().split()]
P = [input() for i in range(N)]

holdCount = 0 

alphabet = [chr(i) for i in range(65, 65+26)]

charCount = {x:0 for x in alphabet}

for i in P:
    charCount[i[0]] += 1 


nonZero = [x for x in charCount if charCount[x] is not 0]
while len(nonZero) >= K:
    for i in sorted(charCount.items(), key=lambda x:x[1])[-K:]:
        charCount[i[0]] -= 1
    holdCount += 1
    nonZero = [x for x in charCount if charCount[x] is not 0]

print(holdCount)

Solution (Python):
n, k = map(int, raw_input().split())
d = {}
for _ in xrange(n):
    s = raw_input().strip()
    d[s[0]] = d.get(s[0], 0) + 1
for i in xrange(n / k, 0, -1):
    c = t = 0
    for _, j in d.viewitems():
        j = min(j, i)
        c += j
        if c >= i:
            t += 1
            c -= i
    if t >= k:
        print i
        break
else:
    print 0

Solution (Python):
from collections import Counter
n, k = map(int, input().split())
ps = [input() for _ in range(n)]
heads = Counter((p[0] for p in ps))
ans = 0
while len(heads) >= k:
    ans += 1
    for h, c in heads.most_common()[:k]:
        if c==1:
            heads.pop(h)
        else:
            heads[h] -= 1
print(ans)

Solution (Python):


import collections


def solve(k, ps):
    ctr = collections.Counter(p[0] for p in ps)
    ans = 0
    while len(ctr) >= k:
        mc = (char for char, _ in ctr.most_common(k))
        ctr.subtract(mc)
        ans += 1
        ctr = collections.Counter(dict(
                                  item for item in ctr.items() if item[1]))
    return ans


def main():
    n, k = map(int, input().split())
    ps = [input() for _ in range(n)]
    print(solve(k, ps))


if __name__ == '__main__':
    main()

Solution (Python):
def solve():
	N,K = map(int,raw_input().split())
	P = [0]*26
	for i in xrange(N):
		P[ord(raw_input()[0])-65] += 1
	P.sort()
	ans = 0
	for i in xrange(N):
		pos = 25
		cnt = K
		while pos >= 0:
			if cnt == 0:
				ans += 1
				break
			if P[pos] > 0:
				P[pos] -= 1
				cnt -= 1
			pos -= 1
		else:
			return ans
		P.sort()
	return ans
print solve()

Solution (Python):
n,k=map(int,raw_input().split())
p=[raw_input() for _ in xrange(n)]
cnt=0
pr=[0]*26

for i in xrange(n):
    pr[ord(p[i][0])-ord('A')]+=1

for i in xrange(26):
    if pr[i]>0:
        cnt+=1
if k>cnt:
    print(0)
else:
    ans=0
    while pr!=[0]*26:
        pr.sort()
        pr.reverse()
        tmp=k
        for i in xrange(26):
            if tmp==0:
                ans+=1
                break
            if pr[i]>0:
                tmp-=1
                pr[i]-=1
    print(ans)