문제 출처
1. 문제설명
- 스위치의 상태는 0(꺼짐) 또는 1(켜짐)로 부여된다.
- 성별과 받은 수에 따라 스위치를 조작한다.
- 남학생은 받은 번호의 배수인 스위치의 상태를 바꾼다.
- 여학생은 자신의 번호를 중심으로 상태가 대칭인 지점까지 스위치를 바꾼다.
2. 알고리즘 설계
- 처음 이해를 잘못했던 게 아래 문구 때문이었다.
- 같은 번호가 붙은 스위치를 중심으로 좌우가 대칭이면서 가장 많은 스위치를 포함하는 구간을 찾아서,
- 가장 많은 스위치를 포함하는 대칭 구간을 찾아야 하는 줄 알았다.
- 예를 들어서, 받은 번호가 3이라고 해보자.
- 3을 중심으로
[4,5]
가 대칭이고,
- 좌우 약 10칸 떨어진 구간에 대칭 스위치가 3개인 구간이 있다면?
[4,5]
만 바꾸면 된다.
- 본인이 하고 싶은 말은, 스위치를 중심으로 라는 문구를 잘 확인해야 한다는 것이다.
3. 로직
- 남학생의 구현은 매우 간단하다.
cur_switch = !cur_switch;
- 0 또는 1이므로, 간단하게 구현 가능하다.
- if-else 문을 쓰지말자
- 여학생 구현
- 자기 번호 위치의 스위치는 무조건 상태가 바뀐다.
- 스위치 번호의 -i, +i번째가 같아질 때까지 스위치의 상태를 바꾼다.
- 다르다면, 즉시 종료한다.
4. 전체 코드
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int n; cin >> n;
vector<int> v(n + 1);
for (int i = 1; i <= n; i++)
cin >> v[i];
int std_num; cin >> std_num;
for (int i = 0; i < std_num; i++) {
int sex, switch_num;
cin >> sex >> switch_num;
if (sex == 1) {
for (int i = switch_num; i <= n; i += switch_num)
v[i] = !v[i];
}
else {
v[switch_num] = !v[switch_num];
for (int i = 1; v[switch_num - i] == v[switch_num + i]; i++) {
if (switch_num + i > n || switch_num - i < 1) break;
v[switch_num - i] = !v[switch_num - i];
v[switch_num + i] = !v[switch_num + i];
}
}
}
for (int i = 1; i <= n; i++) {
cout << v[i] << " ";
if (i % 20 == 0) cout << "\n";
}
return 0;
}
5. 소감
- 정답률 19%(2023-06-04 기준)로 극악인 문제인줄 알았는데,
- 생각보다 간단한 문제라서 당황했다.
- 아마 내 생각에는 여학생 스위치 바꾸는 구현에서 많이 틀리지 않았을까 싶다.