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

U·2023년 8월 2일

백준

목록 보기
36/116

💻 문제


일단 생각하기!

  • ① 남학생일 경우 ② 여학생일 경우로 나눠서 생각한다.
    남학생일땐, 받은 수의 배수 위치인 스위치의 상태를 바꾸면 된다.
    여학생일때가 조금 복잡한데, 자신의 위치를 기준으로 양쪽 스위치가 같은 수, 즉 대칭이면 그 다음 스위치도 대칭인지 검사한다. 만약 어느 시점에서 대칭이 아닐 경우 대칭인 왼쪽 스위치부터 오른쪽 스위치까지 상태를 바꿔준다.
    또한, 스위치가 20개를 넘을 경우, 20개째 스위치에서 줄 바꿈을 해준다.
  • 위의 로직을 코드로 옮기려니 많이 복잡해졌다. 재귀함수에 대한 이해가 아직 완벽하게 되지 않아서 추후에 재귀 함수를 이용하여 풀어보려고 한다.

풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
/**
 * @author 김유나
 * 2023-08-01
 * [문제] 백준 1244번 스위치 켜고 끄기
 * [아이디어] (1) 남학생일 경우 부여받은 번호의 배수일때 스위치 상태 바꾸기
 * 			(2) 여학생일 경우 부여받은 번호의 양쪽이 대칭인지 확인, 대칭이라면 +-2, +-3,... 확인 후 대칭이 아니라면
 * 				대칭인 부분의 스위치 상태 바꾸기
 */

public class BJ_1244_스위치켜고끄기_김유나 {
	public static void main(String[] args) throws NumberFormatException, IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int switchN = Integer.parseInt(br.readLine()); // 스위치 개수 입력 받기
		int switchs[] = new int[switchN]; // 스위치 상태 : 배열 사용
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		for (int i = 0; i < switchN; i++) {
			switchs[i] = Integer.parseInt(st.nextToken()); // 스위치 상태 입력 받기
		}
		
		int studentN = Integer.parseInt(br.readLine()); // 학생 수 입력 받기
		int students[][] = new int[studentN][2]; // 학생 성별, 받은 수 : 2차원 배열 시용
		
		for (int i = 0; i < studentN; i++) {
			st = new StringTokenizer(br.readLine());
			students[i][0] = Integer.parseInt(st.nextToken()); // 성별 입력 받기
			students[i][1] = Integer.parseInt(st.nextToken()); // 받은 수 입력 받기
		}
		
		switchRun(switchs, students); // 스위치 켜고 끄기 시작
		
	}
	static void switchRun(int[] switchs, int [][] students) {
		int sLength = switchs.length;
		
		for (int i = 0; i < students.length; i++) {
			// if 남학생일 때
			if (students[i][0] == 1) {
				for (int j = 1; j <= sLength / students[i][1]; j++) {
					// 받은 수의 배수 스위치 상태 바꾸기
					switchs[students[i][1] * j - 1] = switchs[students[i][1] * j - 1] == 0 ? 1 : 0;
				}
			}
			// else if 여학생이면
			else if (students[i][0] == 2) {
				int minIdx = Math.min(sLength - students[i][1] + 1, students[i][1]);  // 검증할 최소 반복 횟수
				int stopIdx = -1; // 상태 변경 반복할 횟수
				
				if (students[i][1] == 1 || students[i][1] == sLength) { // 1 또는 마지막 수일 경우
					switchs[students[i][1] - 1] = switchs[students[i][1] - 1] == 0 ? 1 : 0; // 그 자리만 상태 변경 : 대칭을 이룰 수 없기 때문
				}
				
				else {
					for (int j = 0; j <= minIdx - 1; j++) {
						if (j == 0) switchs[students[i][1] - 1] = switchs[students[i][1] - 1] == 0 ? 1 : 0;
						// 본인인 경우 상태 변경
						else {
							if (switchs[students[i][1] - 1 - j] == switchs[students[i][1] - 1 + j]) {
								stopIdx = j; // 상태 변경 반복할 횟수 저장
							}
							else break;
							
						}
					}
					
					for (int j = 1; j <= stopIdx; j++) { // 대칭인 경우 상태 변경
						switchs[students[i][1] - 1 - j] = switchs[students[i][1] - 1 - j] == 0 ? 1 : 0;
						switchs[students[i][1] - 1 + j] = switchs[students[i][1] - 1 + j] == 0 ? 1 : 0;
					}
				}
			}
		}
		
		for (int i = 0; i < sLength; i++) {
			if (i > 0 && i % 20 == 0) { // 20번째 수까지만 출력
				System.out.println();
			}
			System.out.print(switchs[i] + " ");
		}
	}
}
profile
백엔드 개발자 연습생

0개의 댓글