문제 출처 : https://www.acmicpc.net/problem/1652
언어 : Kotlin
문제 설명 :
일 년 동안 세계일주를 하던 영식이는 여행을 하다 너무 피곤해서 근처에 있는 코레스코 콘도에서 하룻밤 잠을 자기로 하고 방을 잡았다.
코레스코 콘도에 있는 방은 NxN의 정사각형모양으로 생겼다. 방 안에는 옮길 수 없는 짐들이 이것저것 많이 있어서 영식이의 누울 자리를 차지하고 있었다. 영식이는 이 열악한 환경에서 누울 수 있는 자리를 찾아야 한다. 영식이가 누울 수 있는 자리에는 조건이 있다. 똑바로 연속해서 2칸 이상의 빈 칸이 존재하면 그 곳에 몸을 양 옆으로 쭉 뻗으면서 누울 수 있다. 가로로 누울 수도 있고 세로로 누울 수도 있다. 누울 때는 무조건 몸을 쭉 뻗기 때문에 반드시 벽이나 짐에 닿게 된다. (중간에 어정쩡하게 눕는 경우가 없다.)
만약 방의 구조가 위의 그림처럼 생겼다면, 가로로 누울 수 있는 자리는 5개이고, 세로로 누울 수 있는 자리는 4개 이다. 방의 크기 N과 방의 구조가 주어졌을 때, 가로로 누울 수 있는 자리와 세로로 누울 수 있는 자리의 수를 구하는 프로그램을 작성하시오.
- 첫째 줄에 방의 크기 N이 주어진다. N은 1이상 100이하의 정수이다. 그 다음 N줄에 걸쳐 N개의 문자가 들어오는데 '.'은 아무것도 없는 곳을 의미하고, 'X'는 짐이 있는 곳을 의미한다.
- 첫째 줄에 가로로 누울 수 있는 자리와 세로로 누울 수 있는 자리의 개수를 출력한다.
제한 사항 :
- 시간 제한 : 2초
- 메모리 제한 : 128MB
입출력 예 :
입력 | 출력 |
5 ....X ..XX. ..... .XX.. X.... |
5 4 |
풀이 :
영식이가 누울 수 있는 최소 크기 1X2 or 2X1. 최대는 상관없음.
문제 예시에는 일부러 안내준거 같은데, 한 줄에 한 공간이 아니라 00X00 인 경우 누울 공간 2자리라고 생각해야한다.
그래서 가로든 세로든 다음과 같은 순서가 생긴다.
'.'이 나온다면 size에 증가시킨다.
'X'가 나온다면, size가 음수가 나오면 안되기 때문에 size가 0이 아닐때 size를 감소시킨다.
size가 2가 됐다면, 누울 공간이 되므로 체크리스트에 추가시키고, 사이즈는 초기화 시킨다.
그렇지만 이대로 진행하면 다음에 또 연달아 사이즈가 2가 나왔을때 누울 공간이 되버린다.
0000X <-- 실제로 누울 공간은 1자리지만, 위 명령대로라면 누울 공간은 2자리가 된다.
그래서 이전게 X인지 O인지 판별하는 것도 좋지만 Boolean을 사용해 처리했다.
size가 2가 될때, false였던 값을 true로 변경시키고 true일때 진행하는 명령은 'X'가 나왔는지 아닌지를 판별하고 X가 나왔다면 false로 값을 변경해 원래 명령을 실행하도록 한다.
00X00 <-- 그렇다면 이 라인을 해결할 수 있게 된다.
최종적으로 완성된 순서는 다음과 같다.
1. lineCheker가 false라면,
1-1. '.'일때, size++
1-2. 'X'이고, size !=0라면 size--
1-3. size == 2일때, checkList++; size == 0; lineCheker = true;
2. lineChecker가 true라면,
2-1. 'X'일때, lineCheker = false
이걸 중첩반복문에서 수행하여 이차원배열을 순회하게하면 된다.
가로든, 세로든 방식은 바뀌지 않기 때문에 값을 저장하는 공간만 제대로 구분해주고 i와 j를 바꾸기만하면 가로든 세로든 통용된다.
import java.io.BufferedWriter
import java.io.OutputStreamWriter
fun main() = with(System.`in`.bufferedReader()) {
val bw = BufferedWriter(OutputStreamWriter(System.out))
val n = readLine().toInt()
val room = Array(n) { Array(n) { '.' } }
val checkList = IntArray(2) { 0 }
repeat(n) {
readLine().onEachIndexed { index, c ->
if (room[it][index] != c) room[it][index] = c
}
}
for (i in 0 until n) {
val size = IntArray(2) { 0 }
val line = BooleanArray(2) { false }
for (j in 0 until n) {
if (!line[0]) {
if (room[i][j] == '.') size[0]++
if (room[i][j] == 'X' && size[0] != 0) size[0]--
if (size[0] == 2) {
checkList[0]++
size[0] = 0
line[0] = true
}
} else {
if (room[i][j] == 'X') line[0] = false
}
if (!line[1]) {
if (room[j][i] == '.') size[1]++
if (room[j][i] == 'X' && size[1] != 0) size[1]--
if (size[1] == 2) {
checkList[1]++
size[1] = 0
line[1] = true
}
} else {
if (room[j][i] == 'X') line[1] = false
}
}
}
bw.appendLine(checkList.joinToString(" "))
bw.flush()
bw.close()
}
'백준 > 문제' 카테고리의 다른 글
2711번: 오타맨 고창영 (1) | 2023.12.06 |
---|---|
12904번: A와 B (2) | 2023.12.05 |
1919번: 애너그램 만들기 (0) | 2023.12.01 |
2864번: 5와 6의 차이 (0) | 2023.12.01 |
1159번: 농구 경기 (1) | 2023.11.30 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!