| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- CDC
- 스프링
- 프로젝트
- boj
- K8S
- debezium
- 헥사고날 아키텍처
- OpenAI
- C++
- 로버트 C. 마틴
- 레이어드 아키텍처
- 톰 홀버그
- EDA
- chatGPT
- MSA
- Kafka
- 엉클 밥
- 로버트마틴
- 배치
- vm
- API
- 백준
- 개발
- outbox
- 클린 아키텍처
- 자바
- PS
- JPA
- 김영한
- Spring
- Today
- Total
코딩 해파리
[BOJ/백준] C++ 27113 잠입 본문
안녕하세요! 백준 27113번 잠입 문제에 대한 분석과 해결 방법을 소개해드리겠습니다. 이 문제는 그리디 알고리즘을 활용하여 해결할 수 있는 재미있는 문제입니다.
이번 문제의 경우에는 solved에서 제공하는 난이도 기준으로는 골드 5에 해당합니다! 근데 사실... 고려할 사항도 너무 많고, 예외처리가 빡쌔기 때문에... 체감 난이도는 훨씬 높다고 생각합니다!
문제 분석:
이 문제는 N개의 행과 M개의 열로 이루어진 격자 모양의 적군의 기지에서 최 상병이 안전하게 탈출할 수 있는지를 판단하는 문제입니다. 각 행에는 센서가 있어 최 상병의 이동을 방해할 수 있습니다. 우리의 목표는 최 상병이 첫 번째 행의 가장 왼쪽 칸에서 시작하여 마지막 행의 아무 칸으로 이동할 수 있는지 확인하는 것입니다.
그리디 알고리즘 접근:
이 문제를 해결하기 위해 그리디 알고리즘을 사용했습니다. 그리디 알고리즘의 핵심 아이디어는 각 단계에서 가장 최적의 선택을 하는 것입니다. 이 문제에서는 각 행을 지날 때마다 가능한 가장 왼쪽 칸으로 이동하는 전략을 사용했습니다. 또한, 자율 방범 로봇에게 걸리지 않고 목표지점까지 간다는 말은 최단거리로 이동해야만 한다는 것임을 명심해야 합니다. 그러므로, 왼 쪽으로 이동하거나 위 쪽으로 이동해서는 안 됩니다!
해결 방법:
1. 현재 위치(cur)를 1로 초기화하고, 각 행을 순차적으로 검사합니다.
2. 각 행에서 센서의 정보를 입력받고, 다음과 같이 처리합니다:
- 센서가 없는 경우: 그대로 통과
- 센서가 1개인 경우: 센서의 방향에 따라 이동 가능 여부를 판단하고, 필요시 위치를 조정
- 센서가 2개인 경우: 센서들의 방향과 위치에 따라 이동 가능한 경로를 찾고, 위치를 조정
3. 만약 어떤 단계에서든 이동이 불가능하다고 판단되면, "NO"를 출력하고 프로그램을 종료합니다.
4. 모든 행을 무사히 통과하면 "YES"를 출력합니다.
결과 출력:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N, M, cur{1};
void terminateOnImpossibility() {
cout << "NO" << '\n';
exit(0);
}
void moveCur(int k) {
if (k == 0) {
return;
} else if (k == 1) {
int start;
char dir;
cin >> start >> dir;
if (dir == 'R') {
if (cur > start - 1) {
terminateOnImpossibility();
}
} else {
if (start == M) {
terminateOnImpossibility();
}
cur = max(cur, start + 1);
}
} else {
int start1, start2;
char dir1, dir2;
cin >> start1 >> dir1 >> start2 >> dir2;
if (dir1 == dir2) {
int start;
if (dir1 == 'R') {
start = min(start1, start2);
if (cur > start - 1) {
terminateOnImpossibility();
}
} else {
start = max(start1, start2);
if (start == M) {
terminateOnImpossibility();
}
cur = max(cur, start + 1);
}
} else {
if (dir1 == 'L' && dir2 == 'R') {
swap(start1, start2);
}
if (start1 <= start2) { //센서 사이만 통과 불가
if (cur >= start1) {
if (start2 == M) {
terminateOnImpossibility();
}
cur = max(cur, start2 + 1);
}
} else if (start1 > start2) { //센서 사이만 통과 가능
if (cur >= start1 || start1 - start2 == 1) {
terminateOnImpossibility();
}
cur = max(cur, start2 + 1);
}
}
}
}
void Solve() {
for (int i = 1; i < N; i++) {
int k;
cin >> k;
moveCur(k);
}
cout<<"YES"<<'\n';
}
void Init() {
cin >> N >> M;
}
int main() {
cin.tie(nullptr)->ios_base::sync_with_stdio(false);
Init();
Solve();
return 0;
}
코드 설명:
- `moveCur` 함수는 각 행에서의 이동을 처리합니다. 센서의 개수와 위치, 방향에 따라 다양한 경우를 고려하여 최적의 이동을 결정합니다.
- `terminateOnImpossibility` 함수는 이동이 불가능한 상황을 처리합니다.
- `Solve` 함수에서는 각 행을 순회하며 `moveCur` 함수를 호출하여 이동을 시뮬레이션합니다.
이 접근 방식의 장점은 각 단계에서 최선의 선택을 함으로써 전체적으로 최적의 결과를 얻을 수 있다는 것입니다. 또한, 시간 복잡도 측면에서도 효율적인데, 각 행을 한 번씩만 검사하므로 O(N) 시간 복잡도를 가집니다!
결론:
이 문제는 그리디 알고리즘을 활용하여 효과적으로 해결할 수 있는 좋은 예시입니다. 각 단계에서 최선의 선택을 하면서도 전체적인 목표를 달성할 수 있음을 보여줍니다. 이러한 접근 방식은 실제 문제 해결 상황에서도 유용하게 적용될 수 있다고 봅니다,,!
이 글이 여러분의 알고리즘 학습에 도움이 되었기를 바라며... 혹시 문제와 관련해서 궁금한 점이나 오타 등은 댓글 남겨주세요!
'Algorithm > BOJ' 카테고리의 다른 글
| [BOJ/백준] C++ 2457 공주님의 정원 (0) | 2024.08.17 |
|---|---|
| [BOJ/백준] 22862 C++ 가장 긴 짝수 연속한 부분 수열 (large) (1) | 2024.08.13 |
| [BOJ/백준] 21736 C++ 헌내기는 친구가 필요해 (5) | 2023.07.18 |
| [BOJ/백준/알고리즘] 1717 C++ 집합의 표현 with 분리집합 개념 (6) | 2023.07.15 |
| [BOJ/백준] 14940 C++ 쉬운 최단거리 (2) | 2023.07.13 |