[BOJ] 1244번 스위치켜고끄기 - JAVA

최영환·2024년 8월 21일
0
post-thumbnail

💡 문제

💬 입출력 예시

📌 풀이(소스코드)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

        int M = Integer.parseInt(br.readLine());
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int gender = Integer.parseInt(st.nextToken());
            int num = Integer.parseInt(st.nextToken());

            status[num] = Math.abs(status[num] - 1);    // 받은 번호의 위치는 항상 바뀐다.

            // 남학생일 경우
            if (gender == 1) {
                for (int j = 1; j <= N; j++) {
                    if (j % num == 0 && j != num) {
                        status[j] = Math.abs(status[j] - 1);
                    }
                }
            } else if (gender == 2) {
                // 여학생일 경우
                for (int j = 1; j <= N / 2; j++) {
                    int left = num - j;
                    int right = num + j;
                    if (left <= 0 || right >= N + 1) {
                        break;
                    }
                    if (status[left] != status[right]) {
                        break;
                    }
                    status[left] = Math.abs(status[left] - 1);
                    status[right] = Math.abs(status[right] - 1);
                }
            }
        }
        
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i < status.length; i++) {
            sb.append(status[i]).append(" ");
            if (i % 20 == 0) {
                sb.append("\n");
            }
        }
        System.out.println(sb);
    }
}

📄 해설

접근

  • 역시 구현 문제로 문제에서 주어진 조건을 충실히 이행하면 되는 문제
  • 구현문제로 넘어오니, 실버 문제의 구현 자체에는 큰 어려움들이 없다. (아직 하위 단계라 그런 것 같긴하다 😂)
  • 남학생인 경우의 처리와 여학생인 경우의 처리로 나누어서 구현하면 되며, 각 학생에게 부여된 번호에 해당하는 위치는 무조건 상태가 변하므로, 해당 위치의 상태는 미리 바꾼 다음 나머지 값들에 대한 처리를 했다.
  • 남학생은 해당 인덱스가 배수인지 아닌지만 확인하면 되므로 간단하지만, 여학생의 경우가 좀 복잡할 수 있다. 여학생의 경우는 입력받은 위치를 중심으로 양 옆의 위치들을 확인해야한다.
  • 자세한 구현은 코드와 아래 과정 설명을 확인하길 바란다.

과정

  • 스위치의 개수 N 을 입력 받고 스위치의 상태를 저장할 배열 status 에 스위치의 시작 상태를 입력받는다.
  • 학생의 수 M 을 입력 받고 각 학생의 성별과 번호를 입력받는다.
  • 어떤 경우에도 입력 받은 번호 num 위치의 스위치 상태는 변하므로, 해당 위치는 미리 변경을 해둔다. 학생의 성별에 따라 다음과 같이 처리를 한다.
    • 남학생의 경우
      1. status 배열을 순회하면서 해당 인덱스의 값이 num 과 일치하는지와 num 의 배수인지를 확인한다.
      2. 1 에 해당하면 해당 위치의 상태 값을 바꾼다.
    • 여학생의 경우
      1. 대칭 검사를 위해 leftright 라는 변수를 사용한다. 해당 값들은 num 에서 j 만큼을 더하고 뺀 값이며, j 는 1 부터 N/2 까지의 값이다. (num 위치를 중심으로 탐색해 나가기 위함)
      2. leftright 값이 배열의 범위를 벗어나거나 두 위치의 상태가 대칭을 이루지 않으면 반복을 종료한다.
      3. 2 의 조건을 모두 통과했다면 해당 위치는 대칭을 이루는 값들이므로 상태 값을 변경해준다.
  • 위 과정을 모두 끝냈다면 현재 status 배열의 상태를 출력한다. 이때, 출력 조건을 따라 20번째 원소를 출력할 때마다 줄바꿈을 해준다. 출력을 한번만 수행하기 위해 StringBuilder 를 사용한다.
profile
조금 느릴게요~

0개의 댓글