[백준 2138번 C/C++] 전구와 스위치
[백준 2138번 C/C++] 전구와 스위치
https://www.acmicpc.net/problem/2138
해결전략
그리디 알고리즘 Greedy Algorithm
정답코드
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int n; // 스위치의 개수를 저장할 변수
string initial; // 초기 문자열
string target; // 목표 문자열
void ToggleSwitch(int k, string& v) // 스위치를 조작하는 함수, k번째 스위치를 누르면 k-1, k, k+1의 상태가 변경됨
{
if (0 <= k - 1)
v[k - 1] = v[k - 1] == '0' ? '1' : '0';
if (0 <= k && k < n)
v[k] = v[k] == '0' ? '1' : '0';
if (k + 1 < n)
v[k + 1] = v[k + 1] == '0' ? '1' : '0';
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); // 입출력 속도 향상을 위한 설정
cin >> n;
cin >> initial; // 초기 문자열 입력
cin >> target; // 목표 문자열 입력
string tmp1 = initial; // 첫번째 시나리오를 위한 임시 문자열
string tmp2 = initial; // 두번째 시나리오를 위한 임시 문자열
// 첫 번째 스위치를 누르는 경우의 시나리오
ToggleSwitch(0, tmp1); // 첫번째 스위치 누름
int cnt1 = 1; // 스위치 누른 횟수 카운트 (이미 1번 누름)
for (int i = 0; i < n; i++) // 두 번째 스위치부터 마지막 스위치까지 반복
{
// 현재 상태가 목표와 다를 경우
if (tmp1[i] != target[i])
{
if (i == n - 1) { // 마지막 스위치인데 목표와 다를 경우 실패
cnt1 = -1;
break;
}
ToggleSwitch(i + 1, tmp1); // 다음 스위치 누름
cnt1++;
}
// 더 이상 확인하지 않을 이전 위치가 다른 경우가 다른 경우
if (0 <= i - 1 && tmp1[i - 1] != target[i - 1]) {
cnt1 = -1;
break;
}
}
// 첫 번째 스위치를 누르지 않는 경우의 시나리오
int cnt2 = 0; // 스위치 누른 횟수 카운트
for (int i = 0; i < n; i++) // 첫 번째 스위치부터 마지막 스위치까지 반복
{
// 현재 상태가 목표와 다를 경우
if (tmp2[i] != target[i])
{
if (i == n - 1) { // 마지막 스위치인데 목표와 다를 경우 실패
cnt2 = -1;
break;
}
ToggleSwitch(i + 1, tmp2); // 다음 스위치 누름
cnt2++;
}
// 더 이상 확인하지 않을 이전 위치가 다른 경우가 다른 경우
if (0 <= i - 1 && tmp2[i - 1] != target[i - 1]) {
cnt2 = -1;
break;
}
}
int answer; // 최종 답안
// 두 시나리오 모두 실패, 하나만 성공, 둘 다 성공한 경우를 나누어 처리
if (cnt1 == -1 && cnt2 == -1) answer = -1;
else if (cnt1 == -1 && cnt2 != -1) answer = cnt2;
else if (cnt1 != -1 && cnt2 == -1) answer = cnt1;
else answer = min(cnt1, cnt2); // 둘 다 성공한 경우 더 적은 횟수 선택
cout << answer; // 최종 답안 출력
return 0; // 프로그램 종료
}
정답코드룰 간략화한 버젼
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int n;
string initial, target;
void toggleSwitch(string& v, int k) {
for (int i = k - 1; i <= k + 1; i++) {
if (i >= 0 && i < n) {
v[i] = v[i] == '0' ? '1' : '0';
}
}
}
int solve(string v, bool pressFirst)
{
int cnt = 0;
if (pressFirst) {
toggleSwitch(v, 0);
cnt++;
}
for (int i = 1; i < n; i++) {
if (v[i - 1] != target[i - 1]) {
toggleSwitch(v, i);
cnt++;
}
}
if (v != target) return -1;
return cnt;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> initial >> target;
int cnt1 = solve(initial, true); // 첫 번째 스위치를 누른 경우
int cnt2 = solve(initial, false); // 첫 번째 스위치를 누르지 않은 경우
if (cnt1 == -1 && cnt2 == -1) cout << -1;
else if (cnt1 == -1) cout << cnt2;
else if (cnt2 == -1) cout << cnt1;
else cout << min(cnt1, cnt2);
return 0;
}
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 16287번 C/C++] Parcel (0) | 2024.07.17 |
---|---|
[백준 11401번 C/C++] 이항 계수 3 (0) | 2024.06.02 |
[백준 15685번 C/C++] 드래곤 커브 (0) | 2024.05.07 |
[백준 16236번 C/C++] 아기 상어 (0) | 2024.05.04 |
[백준 14499번 C/C++] 주사위 굴리기 (0) | 2024.05.04 |
댓글
이 글 공유하기
다른 글
-
[백준 16287번 C/C++] Parcel
[백준 16287번 C/C++] Parcel
2024.07.17 -
[백준 11401번 C/C++] 이항 계수 3
[백준 11401번 C/C++] 이항 계수 3
2024.06.02 -
[백준 15685번 C/C++] 드래곤 커브
[백준 15685번 C/C++] 드래곤 커브
2024.05.07 -
[백준 16236번 C/C++] 아기 상어
[백준 16236번 C/C++] 아기 상어
2024.05.04