1부터 연속적으로 번호가 붙어있는 스위치들이 있다. 스위치는 켜져 있거나 꺼져있는 상태이다. <그림 1>에 스위치 8개의 상태가 표시되어 있다. ‘1’은 스위치가 켜져 있음을, ‘0’은 꺼져 있음을 나타낸다. 그리고 학생 몇 명을 뽑아서, 학생들에게 1 이상이고 스위치 개수 이하인 자연수를 하나씩 나누어주었다. 학생들은 자신의 성별과 받은 수에 따라 아래와 같은 방식으로 스위치를 조작하게 된다.
남학생은 스위치 번호가 자기가 받은 수의 배수이면, 그 스위치의 상태를 바꾼다. 즉, 스위치가 켜져 있으면 끄고, 꺼져 있으면 켠다. <그림 1>과 같은 상태에서 남학생이 3을 받았다면, 이 학생은 <그림 2>와 같이 3번, 6번 스위치의 상태를 바꾼다.
여학생은 자기가 받은 수와 같은 번호가 붙은 스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서, 그 구간에 속한 스위치의 상태를 모두 바꾼다. 이때 구간에 속한 스위치 개수는 항상 홀수가 된다.
O(N*S)
정도의 로직으로도 충분히 제한 시간 안에 통과할 수 있을 것이라 예상했다.int
보다 boolean
자료형으로 관리하는 것이 더 명확하고 메모리 효율적이라고 생각했다.N+1
로 선언하고 인덱스 1부터 사용하는 전략을 선택했다.N+1
인 boolean
배열 switches
를 생성한다.StringTokenizer
를 사용해 N개의 초기 스위치 상태를 switches
배열의 1번 인덱스부터 저장한다. ("1"이면 true
, "0"이면 false
)for
문을 num
부터 시작하여 num
씩 증가시키면서 N
까지 반복한다. (j = num; j <= N; j += num
)switches[j] = !switches[j]
)num
위치의 스위치 상태를 반전시킨다.while
문을 사용해 중심으로부터의 거리 d
를 1씩 증가시키며 좌우 대칭을 검사한다.num - d
)가 1보다 크거나 같고, 우측 인덱스(num + d
)가 N보다 작거나 같아야 한다.switches[num - d]
와 switches[num + d]
의 상태가 같다면, 두 스위치의 상태를 모두 반전시킨다.break
를 통해 while
문을 즉시 탈출한다.