https://www.acmicpc.net/problem/1244
문제
1부터 연속적으로 번호가 붙어있는 스위치들이 있다. 스위치는 켜져 있거나 꺼져있는 상태이다. <그림 1>에 스위치 8개의 상태가 표시되어 있다. ‘1’은 스위치가 켜져 있음을, ‘0’은 꺼져 있음을 나타낸다. 그리고 학생 몇 명을 뽑아서, 학생들에게 1 이상이고 스위치 개수 이하인 자연수를 하나씩 나누어주었다. 학생들은 자신의 성별과 받은 수에 따라 아래와 같은 방식으로 스위치를 조작하게 된다.
남학생은 스위치 번호가 자기가 받은 수의 배수이면, 그 스위치의 상태를 바꾼다. 즉, 스위치가 켜져 있으면 끄고, 꺼져 있으면 켠다. <그림 1>과 같은 상태에서 남학생이 3을 받았다면, 이 학생은 <그림 2>와 같이 3번, 6번 스위치의 상태를 바꾼다.
여학생은 자기가 받은 수와 같은 번호가 붙은 스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서, 그 구간에 속한 스위치의 상태를 모두 바꾼다. 이때 구간에 속한 스위치 개수는 항상 홀수가 된다.
스위치 번호 |
① | ② | ③ | ④ | ⑤ | ⑥ | ⑦ | ⑧ |
스위치 상태 |
0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
<그림 1>
예를 들어 <그림 2>에서 여학생이 3을 받았다면, 3번 스위치를 중심으로 2번, 4번 스위치의 상태가 같고 1번, 5번 스위치의 상태가 같으므로, <그림 3>과 같이 1번부터 5번까지 스위치의 상태를 모두 바꾼다. 만약 <그림 2>에서 여학생이 4를 받았다면, 3번, 5번 스위치의 상태가 서로 다르므로 4번 스위치의 상태만 바꾼다.
스위치 번호 |
① | ② | ③ | ④ | ⑤ | ⑥ | ⑦ | ⑧ |
스위치 상태 |
0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
<그림 2>
스위치 번호 |
① | ② | ③ | ④ | ⑤ | ⑥ | ⑦ | ⑧ |
스위치 상태 |
1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 |
<그림 3>
입력으로 스위치들의 처음 상태가 주어지고, 각 학생의 성별과 받은 수가 주어진다. 학생들은 입력되는 순서대로 자기의 성별과 받은 수에 따라 스위치의 상태를 바꾸었을 때, 스위치들의 마지막 상태를 출력하는 프로그램을 작성하시오.
해설
문제를 처음 봤을 떄 상당히 쉬울 것이라 생각하였다.
성별이 남자일 땐 배수에 위치한 스위치를 바꿔주고, 여자일 땐 양옆 대칭을 확인하면 된다.
하지만 제출을 했을 때 런타임 에러가 발생하여 이유를 찾아보니 생각지 못한 경우가 있었다.
2
0 0
1
2 2
이런 예제가 있다 하자.
여자가 받은 수는 2이다. 따라서 대칭을 확인해야하는데 스위치는 2개밖에 없다.
이와 같이 대칭할 것이 없을 때가 있다.
사실 처음부터 예외 처리를 잘하면 상관없지만 이런 사소한 것에서 걸려 많이들 틀리는 것 같다.
인덱스를 확인하며 범위를 넘어서는지를 주의해준다면 쉽게 해결할 수 있다.
소스 코드
import java.util.*
lateinit var switch: IntArray
var n = 0
fun main() = with(System.`in`.bufferedReader()) {
n = readLine().toInt()
switch = IntArray(n+1) { 0 }
val st = StringTokenizer(readLine())
repeat(n) { i -> switch[i+1] = st.nextToken().toInt() }
val student = readLine().toInt()
repeat(student) {
val (sex, num) = readLine().split(" ").map { it.toInt() }
turn(sex, num)
}
for(i in 1 until n + 1) {
print("${switch[i]} ")
if(i % 20 == 0) println()
}
}
fun turn(sex: Int, num: Int) {
if(sex == 1) {
for(i in num until switch.size) {
if(i % num == 0) {
if(switch[i] == 0) switch[i] = 1
else switch[i] = 0
}
}
}
else {
var i = num - 1
var j = num + 1
if (switch[num] == 0) switch[num] = 1
else switch[num] = 0
if (!(i < 1 || j > n + 1)) {
while (true) {
if(i < 1 || j > n) break
if(switch[i] != switch[j]) break
if(switch[i] == 0) {
switch[i] = 1
switch[j] = 1
}
else {
switch[i] = 0
switch[j] = 0
}
i--
j++
}
}
}
}
'PS(Problem Solving) > BOJ' 카테고리의 다른 글
[백준/BOJ] 1012번: 유기농 배추 (0) | 2022.02.13 |
---|---|
[백준/BOJ] 2346번: 풍선 터뜨리기 (0) | 2022.02.10 |
[백준/BOJ] 20291번: 파일 정리 (0) | 2022.02.07 |
[백준/BOJ] 1072번: 게임 (0) | 2022.02.07 |
[백준/BOJ] 1449번: 수리공 항승 (0) | 2022.02.07 |
댓글