알고리즘/구현

[BOJ] 백준 1244 - 스위치 켜고 끄기 풀이

송승현(SSH) 2022. 12. 7. 14:54

1. 문제

https://www.acmicpc.net/problem/1244

 

1244번: 스위치 켜고 끄기

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩

www.acmicpc.net

 

2. 풀이

백준 실버 4에 해당하는 구현 및 시물레이션 문제이고 문제를 풀면서 이 문제에서의 핵심 구현 부분은 "여학생"부분이라고 생각했다.

남학생의 경우 본인이 받은 스위치의 번호의 배수에 맞게 0이면 1로, 1이면 0으로 스위치를 변경해주면 된다.

여학생의 경우 3가지의 경우를 생각했다.

1. 받은 스위치의 번호가 1 혹은 스위치의 개수일 경우
 - 이 경우는 왼쪽 혹은 오른쪽 중 하나가 없으므로 비교할 수 없다. 따라서 본인이 받은 스위치 번호에 해당하는 스위치를 바꿔주면 된다.

2. 받은 스위치의 번호 양쪽의 스위치가 다를 경우
 - 이 경우는 문제에 나와있듯이 1번과 동일하게 본인이 받은 스위치 번호에 해당하는 스위치를 바꿔주면 된다.

3. 받은 스위치의 번호가 1 초과 스위치의 개수보다 작고, 받은 스위치의 번호 양쪽의 스위치가 같을 경우
 - 이 경우 부터 탐색을 시작한다. 우선 받은 번호의 스위치의 양쪽은 확인했으므로, start 인덱스와 end 인덱스를 선언하여 각각 받은 번호의 -2, +2한 값을 넣어준다.

- 그 후 반복문을 돌면서 각각의 인덱스가 스위치의 개수 범위를 넘거나 인덱스에 해당하는 스위치가 다를 경우 반복문을 빠져나가며, 이에 아무것도 해당하지 않는 경우 다음 인덱스 탐색을 위해 start에 -1을, end에 +1을 해준다.

- 탐색을 마쳤다면 start에는 +1을, end에는 -1을 해준 범위에 있는 스위치를 변경시켜준다. +1과 -1을 또 하는 이유는 반복문을 빠져나갔다는 것은 범위를 벗어났거나 그 인덱스에 해당하는 값이 다를 경우이기에 그 전의 값으로 반복문의 범위를 설정해야하기 때문이다.

마지막으로 배열의 값을 한 줄당 20개씩 출력해주면 정답!! (이 부분에서 실수가 많았다.)

 

3. 소스 코드

import java.io.*;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        int switchCnt = Integer.parseInt(br.readLine());
        int[] switchArr = new int[switchCnt + 1];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= switchCnt; i++) {
            switchArr[i] = Integer.parseInt(st.nextToken());
        }

        int T = Integer.parseInt(br.readLine());
        while (T > 0) {
            st = new StringTokenizer(br.readLine());
            int sex = Integer.parseInt(st.nextToken());
            int switchNum = Integer.parseInt(st.nextToken());

            switch (sex) {
                case 1:
                    for (int i = switchNum; i <= switchCnt; i = i + switchNum) {
                        switchArr[i] = switchArr[i] == 0 ? 1 : 0;
                    }
                    break;

                case 2:
                    if (switchNum == 1 || switchNum == switchCnt) {
                        switchArr[switchNum] = switchArr[switchNum] == 0 ? 1 : 0;
                    } else if (switchArr[switchNum - 1] != switchArr[switchNum + 1]) {
                        switchArr[switchNum] = switchArr[switchNum] == 0 ? 1 : 0;
                        break;
                    } else {
                        int start = switchNum - 2;
                        int end = switchNum + 2;

                        while (true) {
                            if (start < 1 || end > switchCnt) {
                                break;
                            } else {
                                if (switchArr[start] != switchArr[end]) {
                                    break;
                                } else {
                                    start--;
                                    end++;
                                }
                            }
                        }

                        for (int i = start + 1; i <= end - 1; i++) {
                            switchArr[i] = switchArr[i] == 0 ? 1 : 0;
                        }
                    }
                    break;
            }
            --T;
        }

        for (int i = 1; i <= switchCnt; i++) {
            bw.write(Integer.toString(switchArr[i]) + " ");
            if (i % 20 == 0) {
                bw.write("\n");
            }
        }

        bw.flush();
        bw.close();
        br.close();
    }
}