[Baekjoon] 1244번 스위치 켜고 끄기

Hyeona·2021년 9월 23일
1

📗 Baekjoon

목록 보기
12/14
post-thumbnail

📣
Baekjoon에서 PASS된 코드만 업데이트합니다.
알고리즘을 먼저 풀이하는 언어(Java)가 정해져있어,
풀이 언어(Python, C++, Java)가 모두 업데이트될 때까지는 시간이 걸릴 수 있습니다.



문제 제시


문제

1부터 연속적으로 번호가 붙어있는 스위치들이 있다. 스위치는 켜져 있거나 꺼져있는 상태이다. <그림 1>에 스위치 8개의 상태가 표시되어 있다. ‘1’은 스위치가 켜져 있음을, ‘0’은 꺼져 있음을 나타낸다. 그리고 학생 몇 명을 뽑아서, 학생들에게 1 이상이고 스위치 개수 이하인 자연수를 하나씩 나누어주었다. 학생들은 자신의 성별과 받은 수에 따라 아래와 같은 방식으로 스위치를 조작하게 된다.

남학생은 스위치 번호가 자기가 받은 수의 배수이면, 그 스위치의 상태를 바꾼다. 즉, 스위치가 켜져 있으면 끄고, 꺼져 있으면 켠다. <그림 1>과 같은 상태에서 남학생이 3을 받았다면, 이 학생은 <그림 2>와 같이 3번, 6번 스위치의 상태를 바꾼다.

여학생은 자기가 받은 수와 같은 번호가 붙은 스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서, 그 구간에 속한 스위치의 상태를 모두 바꾼다. 이때 구간에 속한 스위치 개수는 항상 홀수가 된다.

예를 들어 <그림 2>에서 여학생이 3을 받았다면, 3번 스위치를 중심으로 2번, 4번 스위치의 상태가 같고 1번, 5번 스위치의 상태가 같으므로, <그림 3>과 같이 1번부터 5번까지 스위치의 상태를 모두 바꾼다. 만약 <그림 2>에서 여학생이 4를 받았다면, 3번, 5번 스위치의 상태가 서로 다르므로 4번 스위치의 상태만 바꾼다.

입력으로 스위치들의 처음 상태가 주어지고, 각 학생의 성별과 받은 수가 주어진다. 학생들은 입력되는 순서대로 자기의 성별과 받은 수에 따라 스위치의 상태를 바꾸었을 때, 스위치들의 마지막 상태를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에는 스위치 개수가 주어진다. 스위치 개수는 100 이하인 양의 정수이다. 둘째 줄에는 각 스위치의 상태가 주어진다. 켜져 있으면 1, 꺼져있으면 0이라고 표시하고 사이에 빈칸이 하나씩 있다. 셋째 줄에는 학생수가 주어진다. 학생수는 100 이하인 양의 정수이다. 넷째 줄부터 마지막 줄까지 한 줄에 한 학생의 성별, 학생이 받은 수가 주어진다. 남학생은 1로, 여학생은 2로 표시하고, 학생이 받은 수는 스위치 개수 이하인 양의 정수이다. 학생의 성별과 받은 수 사이에 빈칸이 하나씩 있다.

출력

스위치의 상태를 1번 스위치에서 시작하여 마지막 스위치까지 한 줄에 20개씩 출력한다. 예를 들어 21번 스위치가 있다면 이 스위치의 상태는 둘째 줄 맨 앞에 출력한다. 켜진 스위치는 1, 꺼진 스위치는 0으로 표시하고, 스위치 상태 사이에 빈칸을 하나씩 둔다.



문제 풀이


문제가 길기 때문에, 특징을 잘 정리하는게 중요합니다.

가장 중요한 기준은 이 데이터들이 "1"로 시작한다는 것입니다.
들어오는 데이터의 번호와 index의 번호가 차이가 난다는 것이 사전에 오류를 해결할 수 있는 기본적인 방법입니다!

이제 데이터가 순차대로 들어올 것인데, 성별 데이터기준 번호가 옵니다.
여기서 성별에 따라서 기준 번호를 해결하는게 다르게 되는데, 이걸 잘 정리하는게 중요합니다.

남자의 코드가 들어오면, 기준 번호를 포함한 수의 배수들이 반대로 바뀝니다.
여자의 코드가 들어오는 경우가 조금 복잡한데, 기준 번호를 기준으로 좌우 대칭이 되는 데이터를 반전시킵니다.
기준 번호는 말 그대로 기준점으로 포함되기에 이건 항상 홀수가 되는 것이죠.

순차대로 정리하면 다음과 같습니다.
여학생의 코드가 들어오면 대칭이 되는 범위를 잘 체크하는게 결국 풀이의 핵심이 됩니다.



문제 코드


Java

import java.util.Scanner;

public class Main {
  static int N, TOTAL;
  static int[] switchArray;

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    N = sc.nextInt();
    switchArray = new int[N];

    for (int i = 0; i < N; i++)
      switchArray[i] = sc.nextInt();

      TOTAL = sc.nextInt();
      for (int tryCnt = 0; tryCnt < TOTAL; tryCnt++) {
        int gender = sc.nextInt();
        int number = sc.nextInt();

        if (gender == 1) // 남자일 경우 - 배수
          for (int i = (number - 1); i < N; i += number)
            switchArray[i] = (switchArray[i] == 0) ? 1 : 0;
        else { // 여자일 경우 - 대칭확인
          switchArray[number - 1] = (switchArray[number - 1] == 0) ? 1 : 0;
          for (int i = 1; (number-1) - i >= 0 && i + (number-1) < N; i++) {
            if (switchArray[(number-1) - i] == switchArray[(number-1) + i]) {
              switchArray[(number-1) - i] = (switchArray[(number-1) - i] == 0) ? 1 : 0;
              switchArray[(number-1) + i] = (switchArray[(number-1) + i] == 0) ? 1 : 0;
            }
            else break;
        }
      }
    }

    for (int i = 0; i < switchArray.length; i++) {
      System.out.print(switchArray[i] + " ");
      if ((i + 1) % 20 == 0)
        System.out.println();
      }
    sc.close();
  }
}



제출 결과


profile
✍🏻 뭐든 배우면 다 자산이 되겠죠!

0개의 댓글