728x90
문제
N개의 스위치와 N개의 전구가 있다. 각각의 전구는 켜져 있는 상태와 꺼져 있는 상태 중 하나의 상태를 가진다. i(1 < i < N)번 스위치를 누르면 i-1, i, i+1의 세 개의 전구의 상태가 바뀐다. 즉, 꺼져 있는 전구는 켜지고, 켜져 있는 전구는 꺼지게 된다. 1번 스위치를 눌렀을 경우에는 1, 2번 전구의 상태가 바뀌고, N번 스위치를 눌렀을 경우에는 N-1, N번 전구의 상태가 바뀐다.
N개의 전구들의 현재 상태와 우리가 만들고자 하는 상태가 주어졌을 때, 그 상태를 만들기 위해 스위치를 최소 몇 번 누르면 되는지 알아내는 프로그램을 작성하시오.
입력
첫째 줄에 자연수 N(2 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 전구들의 현재 상태를 나타내는 숫자 N개가 공백 없이 주어진다. 그 다음 줄에는 우리가 만들고자 하는 전구들의 상태를 나타내는 숫자 N개가 공백 없이 주어진다. 0은 켜져 있는 상태, 1은 꺼져 있는 상태를 의미한다.
출력
첫째 줄에 답을 출력한다. 불가능한 경우에는 -1을 출력한다.
접근 방식
한 전구의 상태를 바꾸려면 그 전구의 바로 앞 전구에 대한 결정을 미리 해야 하는 것이 중요한 포인트다.
따라서, 첫 번째 전구에 대한 상태를 두가지로 나누어서 풀면된다.
첫번째 전구의 스위치를 누르느냐, 누르지 않느냐
이후로는 현재 전구가 목표 상태의 전구와 다르면 스위치를 누르고, 같다면 스위치를 누르지 않고 진행하면 된다..!
코드
#include <bits/stdc++.h>
using namespace std;
// 스위치 눌렀을 때 해당 인덱스와 좌우 전구를 반전하는 함수
void toggle(string &tmp, int idx) {
for (int i = idx - 1; i <= idx + 1; i++) {
if (i >= 0 && i < tmp.size()) {
tmp[i] = (tmp[i] == '0') ? '1' : '0';
}
}
}
int main() {
int n;
cin >> n;
string str, goal;
cin >> str >> goal;
int ans = INT_MAX;
// 첫번째 전구를 누르지 않은 경우
string tmp = str;
int cnt = 0;
for (int i = 1; i < n; i++) {
if (tmp[i - 1] != goal[i - 1]) {
toggle(tmp, i);
cnt++;
}
}
if (tmp == goal) ans = min(ans, cnt);
// 첫번째 전구를 누른 경우
tmp = str;
cnt = 1; // 첫 번째 전구를 눌렀으므로 카운트를 1로 시작
toggle(tmp, 0);
for (int i = 1; i < n; i++) {
if (tmp[i - 1] != goal[i - 1]) {
toggle(tmp, i);
cnt++;
}
}
if (tmp == goal) ans = min(ans, cnt);
if (ans == INT_MAX) cout << -1;
else cout << ans;
}
728x90
'Algorithm' 카테고리의 다른 글
[BOJ] 수열 2491번 C++ (0) | 2024.10.01 |
---|---|
[BOJ] 다리 놓기 1010번 C++ (1) | 2024.10.01 |
[BOJ] 볼 모으기 17615번 C++ (0) | 2024.09.30 |
[BOJ] 신입 사원 1946번 C++ (2) | 2024.09.25 |
[BOJ] 수 묶기 1744번 C++ (0) | 2024.09.24 |