[백준][1244번: 스위치 켜고 끄기]

호준·2022년 6월 3일
0

Algorithm

목록 보기
76/111
post-thumbnail

🎈문제

문제링크

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. 남자인 경우, 여자인 경우를 나눈다.
  2. 남자인 경우 배수에 해당하는 list 값을 바꾼다.
  3. while문을 통해 대칭이 맞는 경우까지만 돌면서 list 값을 바꾼다.

🎈코드

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

public class Main {
    static int N,K;
    static int[] list;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        list = new int[N];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i=0; i<N; i++){
            list[i] = Integer.parseInt(st.nextToken());
        }
        K = Integer.parseInt(br.readLine());
        for(int i=0; i<K; i++){
            st = new StringTokenizer(br.readLine());

            int FM = Integer.parseInt(st.nextToken());
            int num = Integer.parseInt(st.nextToken());
            if(FM==1){ //남자인 경우
                for(int j=num; j<=N; j+=num){
                    list[j-1] =list[j-1]==0?1:0;
                }
            }else{ // 여자인 경우
                int left = num - 1;
                int right = num + 1;
                while(true) {
                    if (left - 1 >= 0 && right - 1 < N) {
                        if (list[left - 1] == list[right - 1]) {
                            list[left-1] = list[left-1]==0?1:0;
                            list[right-1] = list[right-1]==0?1:0;
                            left--;
                            right++;
                        }else{
                            break;
                        }
                    }else{
                        break;
                    }
                }
                list[num-1] = list[num-1]==0?1:0;
            }
        }
        StringBuilder sb = new StringBuilder();
        for(int i=1; i<=N; i++) {
            sb.append(list[i-1]).append(" ");
            if(i%20==0){
                sb.append("\n");
            }
        }
        System.out.println(sb.toString());
    }
    static void change(int num){
        list[num] = list[num]==0?1:0;
    }

}

🎈알고 넘어가기?

백준 문제를 풀면서 처음 접하는 오류를 접했다.

출력형식이 뭐가 잘못된거지 헤매다가 문제와 조건을 다시 확인해보니 출력조건이 있었다. 출력 조건 : 예를 들어 21번 스위치가 있다면 이 스위치의 상태는 둘째 줄 맨 앞에 출력한다.

for(int i=1; i<=N; i++) {
            sb.append(list[i-1]).append(" ");
            if(i%20==0){ //출력조건
                sb.append("\n");
            }
        }
profile
도전하지 않는 사람은 실패도 성공도 없다

0개의 댓글