문제
IOI 2018 Day 1 첫 번째 문제입니다.
재밌고 쉬운 문제입니다.
풀이
첫 번째 문자는 2번만에 찾을 수 있습니다.
press("AB")가 1인 경우 첫 번째 문자는 A 혹은 B이므로 press("A")의 결과로 알아낼 수 있습니다.
press("AB")가 0인 경우에는 X 혹은 Y이므로 마찬가지로 press("X")로 알아낼 수 있습니다.
일반성을 잃지 않고 첫 번째 문자를 A라 합시다.
그리고 이때까지 우리가 알아낸 $S$의 접두사를 P라 합시다.
$S$의 첫 번째 문자는 뒤에서 다시 나타나지 않으므로 $S$의 접두사를 여러개 붙여서 press를 호출하면 각 접두사마다 press값의 최댓값을 얻는 것과 같습니다.
다음 문자가 B인 경우, X인 경우, 그렇지 않은 경우(Y인 경우)로 나누어지게 잘 접두사를 붙여봅시다.
B인 경우는 P + "B"로 테스트 해 볼 수 있습니다.
X인 경우를 똑같이 P + "X"로 테스트하면 둘을 구분할 수 없으므로 다음 글자가 X인 경우 무조건 길이가 하나 더 길게 나오도록 가능한 모든 경우(P + "XB", P + "XX", P + "XY")를 다 붙여줍시다.
이제 이를 전부 붙여서 press를 호출하면 다음 글자가 무엇인지 한 번만에 알 수 있습니다.
다만 문자열의 길이가 $4N$을 넘어가면 안 되므로 길이를 계산해봅시다.
$\lvert P \rvert + 1 + 3(\lvert P \rvert + 2) = 4\lvert P \rvert + 3$
따라서 식을 정리하면 $\lvert P \rvert \leq N - 2$까지만 한 번만에 다음 글자를 찾을 수 있습니다.
첫 번째 글자를 찾는데 press를 두 번 호출했으므로 $N$번의 호출로 $N - 1$개의 글자를 찾을 수 있습니다.
2번의 호출을 더 할 수 있으므로 마지막은 naive하게 테스트 해 주면 됩니다.
코드
1 | |