문제 출처 : https://www.acmicpc.net/problem/16113
언어 : Kotlin
문제 설명 :
zxcvber는 외계인을 연구하는 과학자다. 그는 지난 10년간 우주에서 오는 시그널를 연구했지만, 아무런 성과가 없었다. 그러던 어느 날, 갑자기 우주에서 이상한 시그널이 오기 시작했다. zxcvber는 매우 기뻐하며 시그널을 받아서 분석해보았다. 시그널은 0과 1로 이루어져 있는데, 여기서는 편의상 0을 ".", 1을 "#"으로 표시한다. 시그널은 다음과 같았다.
###.....###.#..####.#.......#.#....####.....###.#....##.#.......#.#....####.....###.#....#
다른 여러 시그널들을 분석해본 결과, zxcvber는 시그널의 길이가 항상 5의 배수라는 것을 알게 되었다. 시그널을 다섯 개로 쪼개면 뭔가 규칙이 보이지 않을까 생각한 zxcvber는 시그널을 같은 길이의 5개의 시그널로 쪼갰다. 그러자 놀라운 일이 벌어졌다. 아래는 시그널을 쪼갠 뒤 "#"을 검은색, "."을 흰색으로 표시한 그림이다.
시그널은 디지털 숫자를 나타내고 있었다! 1-3열에 8, 9-11열에 3, 13열에 1, 그리고 16-18열에 7이 나타난 것이다. 이 숫자들이 특별한 의미를 갖고 있을 것이라 생각한 zxcvber는 다른 시그널들도 해독을 하기 시작했다. 하지만 시그널들의 길이가 너무 길어서, 일일히 손으로 확인하기에는 한계가 있었다. 다만, 짧은 시그널들을 분석하면서 zxcvber는 시그널의 규칙들을 파악할 수 있었다.
1. 시그널은 "."과 "#"으로 이루어져 있다.
2. 시그널을 해독한 결과에는 반드시 숫자가 1개 이상 있다.
3. 시그널에 등장하는 모든 "#"은 올바른 숫자 패턴에 포함되어 있다.
4. 숫자와 숫자 사이에는 1열 이상의 공백이 있다. 여기서 공백은, 열의 성분이 모두 "."인 열을 의미한다.
5. 0부터 9는 아래와 같이 나타난다. 역시 "#"을 검은색, "."을 흰색으로 표시했다.
주의할 점은, 1은 다른 숫자들과는 다르게 1열을 차지한다는 것이다. zxcvber를 도와 시그널을 해독해보자!
입력 :
입력의 첫 줄에는 시그널의 길이 N(5 ≤ N ≤ 100,000, N은 5의 배수)이 주어진다.
다음 줄에 시그널이 주어진다. zxcvber가 찾아낸 규칙을 따르는 시그널만이 입력으로 주어진다.
출력 :
첫 번째 줄에 시그널을 해독하여 나오는 숫자들을 순서대로 출력한다.
제한 사항 :
- 시간 제한 : 1초 (추가 시간 없음)
- 메모리 제한 : 512MB
입출력 예 :
입력 | 출력 |
40 ###..#..#.#..#..###..#..#.#..#..###..#.. |
81 |
풀이 :
문제에서 주어진 대로 5줄로 나누고 시작한다.
첫번째 줄이 ###으로 시작하면 0, 2, 3, 5, 6, 7, 8, 9 그게 아니라면 1이나 4 둘 중 하나다.
1과 4의 비교는 1은 일직선으로 #이므로 중앙이 .으로 비는 4와는 다르다.
그래서 ###으로 시작하지 않을 때, 일직선 상의 마지막 줄 기준으로 봤을때 #이라면 1 #이 아니라 .이라면 4이다.
0, 2, 3, 5, 6, 7, 8, 9의 경우,
해당 인덱스를 기준으로 5줄 3칸짜리 문자열을 만들어본다.
미리 작성해둔 데이터와 같다면 해당 숫자를 반환한다.
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
fun main() = with(BufferedReader(InputStreamReader(System.`in`))) {
val bw = BufferedWriter(OutputStreamWriter(System.out))
val n = readLine().toInt()
var base = 0
for (i in 1 .. n) {
if (i * 5 == n) {
base = i
break
}
}
val signal = readLine().chunked(base)
val sb = StringBuilder()
var index = 0
while (index < base) {
if (signal[0][index] == '#') {
if (index + 2 <= base) {
// 0, 2, 3, 5, 6, 7, 8, 9
if (signal[0][index + 1] == '#' && signal[0][index + 2] == '#') {
sb.append("${converter(index, signal)}")
index += 3
if (index >= base) break
continue
}
}
// 1, 4
when {
signal[signal.lastIndex][index] == '#' -> sb.append("1")
else -> {
sb.append("4")
index += 3
if (index >= base) break
}
}
}
index++
}
bw.write(sb.toString())
bw.flush()
bw.close()
}
fun converter(index: Int, signal: List<String>): Int {
val sb = StringBuilder()
(0 until 5).forEach { i ->
(0 until 3).forEach { j ->
sb.append(signal[i][j + index])
}
}
val arr = arrayOf(
Pair(0, "####.##.##.####"),
Pair(2, "###..#####..###"),
Pair(3, "###..####..####"),
Pair(5, "####..###..####"),
Pair(6, "####..####.####"),
Pair(7, "###..#..#..#..#"),
Pair(8, "####.#####.####"),
Pair(9, "####.####..####")
)
var result = -1
for (i in arr.indices) {
if (sb.toString() == arr[i].second) {
result = arr[i].first
}
}
return result
}
'백준 > 문제' 카테고리의 다른 글
26004번: HI-ARC (0) | 2024.06.13 |
---|---|
1942번: 디지털시계 (0) | 2024.06.12 |
27522번: 카트라이더: 드리프트 (0) | 2024.06.12 |
17214번: 다항 함수의 적분 (0) | 2024.06.11 |
3486번: Adding Reversed Numbers (0) | 2024.06.11 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!