Algorithm/BaekJoon

[boj 1244.python] '스위치 켜고 끄기' 풀이

쉬지마 이굥진 2024. 1. 15. 17:19

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

 

1244번: 스위치 켜고 끄기

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

www.acmicpc.net


문제

 

이러한 규칙에 따라 학생들이 스위치를 조작하고 난 후의 스위치 상태를 구해야 한다. 

(자세한 입/출력 설명과 예제는 포스팅 상단의 문제를 참고해주길 바란다)


문제 이해

알고리즘 문제 푼 지 2주차가 되어 가니 슬슬 어느 지점에서 어떻게 생각해야 편할지 길이 보이는 것 같기도 하다.

남자와 여자의 행동 양식이 달라서, 남자 여자를 따로 생각하고,

와중에 남자/ 여자가 똑같이 해야하는 부분은 하나의 함수로 빼서 중복 코드를 최대한 없애려고 했다.


문제 풀이 

1. 공통적으로 스위치가 꺼져있으면 키고, 켜져있으면 끄는 행동을 수행하므로 (청개구린가) 스위치 상태 바꾸는 함수를 만들어주자.

def change(num):		# 스위치 상태 바꾸는 함수
    if switch[num] == 0:
        switch[num] = 1
    else:
        switch[num] = 0
    return

 

2. 남자, 여자의 경우를 따로 생각하자.

2-1. 남자의 경우 

받은 스위치 번호의 배수 번호의 스위치를 바꾼다. range의 간격을 이용해서 배수를 찾도록 했다.

if sex == 1:		# 만약에 남자면
        for i in range(num, n+1, num):		# 번호의 배수에 해당하는 스위치를 조작함
            change(i)				# change함수 호출

2-2. 여자의 경우

여자의 경우, 양쪽을 탐색해서 좌우대칭을 찾아줘야 하므로 /2 대신, 정수부분만을 취하는 //2 로 전체 길이를 탐색하도록 해줬다.

# 여자
    else:					# 여자면! 
        change(num)			# change함수 호출
        for k in range(n // 2):		# 좌우 대칭인 범위 확인
            if num + k > n or num - k < 1: # 범위 벗어나면 break
               break
            if switch[num + k] == switch[num - k]:	# (좌우대칭인 범위 내에서) 스위치 상태가 동일하면, 스위치 상태 변경
                change(num + k)			# 좌우대칭인 스위치 중 우측의 스위치 상태 변경
                change(num - k)			# 좌측의 상태도 변경 
            else:									# (좌우대칭인 범위 내에서) 스위치 상태 다르면 break
                break

 

3. 주의: 문제 출력 조건 주의 ,, 한 줄에 20개씩 끊어서 출력해줘야 한다 .. 안하면 틀린다 ...

for i in range(1, n+1):				# 1부터 n까지
    print(switch[i], end = " ")		# 출력 값 사이에 공백 넣어서 출력 (end = " ")
    if i % 20 == 0 :				# 20개씩 스위치 출력 후,
        print()						# 새로운 행으로 넘어가셈

 

 


정답 코드

from sys import stdin
input = stdin.readline

def change(num):			# 스위치 상태 바꾸는 함수
    if switch[num] == 0:
        switch[num] = 1
    else:
        switch[num] = 0
    return

n = int(input())	# 스위치 갯수
switch = [0] + list(map(int, input().split()))		# 스위치의 초기 상태 (인덱스 1부터 시작하게 하기 위해 + [0])
students = int(input())		# 학생 수
for _ in range(students):
    sex, num = map(int, input().split())	# sex: 학생들의 성별, num: 스위치 번호 입력받기
    # 남자
    if sex == 1:
        for i in range(num, n+1, num):		# 자신의 배수에 해당하는 스위치의 상태를 변경함
            change(i)
    # 여자
    else:
        change(num)						# 먼저 스위치 상태 변경
        for k in range(n//2):			# 중심이 되는 스위치로부터 좌우 대칭인 스위치 확인
            if num + k > n or num - k < 1 : break
            if switch[num + k] == switch[num - k]:
                change(num + k)
                change(num - k)
            else:
                break
                
for i in range(1, n+1):				# 최종적인 스위치 상태 출력
    print(switch[i], end = " ")
    if i % 20 == 0:
        print()

마치며

구현 문제 많이 풀어봐야함을 느낀다. 반복만이 살길이다 ㅜㅜ