◎ 이 포스트는 CodeJam 2019의 Round 1A에 대한 설명과 풀이입니다. 자세한 문제 설명은 공식 사이트를 참조하세요. 아래 풀이는 개인적으로 작성한 것으로 CodeJam 공식 Analysis의 내용과 일치하지 않을 수 있습니다.
중국인의 나머지 정리를 이용해 풀이할 수 있다. 총 7번의 Try가 가능하기 때문에 18 이하의 소수 7개 (2, 3, 5, 7, 11, 13, 17)로 매 Try마다 Blade의 수를 통일하면 각 Try에서 방정식을 얻을 수 있다. 여기서 문제는 2 * 3 * 5 * 7 * 11 * 13 * 17 = 510510으로 10^6보다 작다는 것이다. 이 때 2나 3은 제곱하더라도 다른 소수와 서로소이기 때문에 널찍하게 (5, 7, 9, 11, 13, 16, 17)로 Blade를 통일하면 충분히 범위를 커버할 수 있다.
import sys
def extended(a, b):
a, b = max(a, b), min(a, b)
r1, r2 = a, b
s1, s2 = 1, 0
t1, t2 = 0, 1
while r2 > 0:
q = r1 // r2
r1, r2 = r2, r1 - q * r2
s1, s2 = s2, s1 - q * s2
t1, t2 = t2, t1 - q * t2
return ((s1 + b) % b, (t1 + a) % a)
Primes = [5, 7, 9, 11, 13, 16, 17]
L = 5 * 7 * 9 * 11 * 13 * 16 * 17
T, N, M = input().split()
T, N, M = int(T), int(N), int(M)
for tt in range(1, T + 1):
Ret = 0
for prime in Primes:
print (" ".join([str(prime)] * 18))
sys.stdout.flush()
response = sum([int(x) for x in input().split()]) % prime
# x = response (mod prime)
X = (L / prime) % prime
a, b = extended(prime, X)
Ret += (L / prime) * b * response
print (str(int(Ret + L) % L))
최대 50개의 길이를 가지는 1000개의 단어에 대해서 추출가능한 접미사는 총 50000개다. 이 접미사를 최대로 매칭할 수 있는 경우를 찾으면 된다. 가장 간단한 방법은 일치하는 가장 긴 것부터 매치하는 방법이다. ZABCDE, BABCDE, ZCDE, CCDE의 단어가 있다고 하자. (ZABCDE, ZCDE)와 (BABCDE, CCDE)로 쌍을 지으면 CDE가 공통 접미사가 되기 때문에 한 쌍 밖에 만들 수 없다. (ZABCDE, BABCDE)와 (ZCDE, CCDE)로 쌍을 지으면 ABCDE와 CDE가 공통 접미사가 되기 때문에 두 쌍을 만들 수 있다.
즉, 긴 접미사부터 우선적으로 매칭을 시도하면 짧은 접미사에게 영향을 주지 않기 때문에 최대 매칭을 구할 수 있다.
T = int(input())
for tt in range(1, T + 1):
N = int(input())
Words = []
for i in range(N):
Words.append(input())
Suffixs = {}
Dic = {}
for i in range(N):
for j in range(0, len(Words[i])):
length = len(Words[i]) - j
if length not in Suffixs:
Suffixs[length] = []
if Words[i][j:] not in Dic:
Dic[Words[i][j:]] = []
Suffixs[length].append(Words[i][j:])
Dic[Words[i][j:]].append(i)
Used = {}
Ret = 0
keys = list(Suffixs.keys())
keys.sort(), keys.reverse()
for key_ in keys:
for word in Suffixs[key_]:
# check suffix is already used
if word in Used:
continue
# Filter out already used words
for i in range(len(Dic[word]) - 1, -1, -1):
if Dic[word][i] in Used:
del Dic[word][i]
# If pair can't be made, continue
if len(Dic[word]) < 2:
continue
# Mark used index and word.
Used[Dic[word][0]], Used[Dic[word][1]], Used[word] = True, True, True
Ret += 2
print("Case #" + str(tt) + ": " + str(Ret))
출장 오랜만에 출장을 간다. 미국으로 가는 출장은 항상 힘들다. 비행시간은 10시간에서 12시간. 도착해서 시차 극복도…
건강검진 재작년 말인가 작년 1월이었나, 인생 최악의 건강검진 결과를 받고서 다짐했었다. 2025년 건강검진에서는 완벽한 검사결과를…
운동 계획 운동과 식단과 피부관리 동시에 하니 시너지가 엄청나다. 변화가 눈에 보일 정도로 빠르다보니, 성취감도…
This website uses cookies.