[백준 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
댓글을 사용할 수 없습니다.