Goolge Kick Start가 열린다는 메일을 받고 부랴부랴 기출문제를 풀어보았다.
Kick Start는 간단히 말해서 Code Jam 보다 쉬운 대회로, “구글에서 일하기 위해 필요한 기술들을 맛볼 수 있는” 대회라고 한다.
The three-hour rounds feature a variety of algorithmic challenges, all developed by Google engineers so that you get a taste of the technical skills needed for a career at Google.
R과 B로 길이가 N인 문자열을 만들 때, 주어진 p개의 prefix 중 어느 것과도 겹치지 않는 prefix로 시작하는 문자열의 개수를 구하는 문제이다.
풀이는 간단하게 주어진 prefix 로 Trie를 만들고, 루트부터 탐색해서 링크가 끊어지는 부분을 찾아서 개수를 세면 된다.
사용 가능한 문자가 R과 B 뿐이므로 개수는 쉽게 셀 수 있다. ($2^n$ 꼴)
Mural
일렬로 서 있는 n개의 벽에 그림을 그리려 한다.
처음 그림을 그릴 벽은 마음대로 선택할 수 있고,
이후에는 먼저 그림을 그린 벽과 인접한 벽에만 그릴 수 있다.
그림을 하나 그릴 때마다 그림과 인접하지 않은 끝 벽이 한 개씩 무너져내린다고 할 때,
벽이 어떻게 무너지든 상관 없이 확실히 얻을 수 있는 최대의 아름다움을 계산해보자.
(아름다움은 그림이 그려진 벽의 점수 (*문자열로 주어진다) 의 합이다)
그냥 보면 왼쪽 벽이 무너질지 오른쪽 벽이 무너질지 고민이 되지만,
사실 연속된 (n+1) / 2 개의 벽은 모두 선택해볼 수 있다:
그림이 그려진 벽과 인접한 벽 또한 무너지지 않기 때문에,
실제로 무너지기 전에 그림을 그려야 할 벽은 (n+1) / 2 - 2 개가 된다 (양 끝에 인접한 벽에는 가장 마지막에 그리면 되므로).
이러한 조건을 고려하면, 무조건 ‘중간 벽’부터 선택할 경우 예외 없이 항상 그릴 수 있는 것을 확인할 수 있다.
따라서 partial sum 을 구해두고, 가능한 (n+1) / 2 개의 연속된 벽의 아름다움 중 가장 큰 것을 구하면 끝!
Let Me Count The Ways
n 쌍의 커플을 아주 긴 배에 일렬로 태우려 한다.
이중 m 쌍의 신혼 커플은 서로 인접한 자리에 태우지 않는 경우의 수를 구해보자.
Inclusion-Exclusion (포함-배제) 원리 ($|A\cup B| = |A| + |B| - |A\cap B|$) 로 해결할 수 있다.
원래 이런 방법을 이용할 때에는 모든 집합을 살펴보기 때문에 $2^n$ 의 복잡도를 갖지만,
여기서는 각 집합의 크기가 동일하므로 $O(m)$ 개의 집합만 살펴보면 해결할 수 있다.
귀찮은 점으로는, n 과 m 이 큰 경우가 있어서 큰 수 모듈러 계산을 해야한다는 것이 있다.