diff --git a/week07/seoyoung.md b/week07/seoyoung.md new file mode 100644 index 0000000..258461a --- /dev/null +++ b/week07/seoyoung.md @@ -0,0 +1,168 @@ +# 7주차 문제 풀이 인증 + +## 기본 정보 + +- 이름: 이서영 +- 목표 문제 수: 3 +- 실제 풀이 문제 수: 3 + +## 푼 문제 목록 + +| 번호 | 문제 이름 | 난이도 | 링크 | 풀이 여부 | +| -- | ----- | --- | --------------------------------------------------------------- | ----- | +| 1 | 거리두기 확인하기 | Lv.2 | https://school.programmers.co.kr/learn/courses/30/lessons/81302 | o | +| 2 | [1차] 프렌즈4블록 | Lv.2 | https://school.programmers.co.kr/learn/courses/30/lessons/17679 | o | +| 3 | 기둥과 보 설치 | Lv.3 | https://school.programmers.co.kr/learn/courses/30/lessons/60061 | o | + +--- + +# 오답노트 + +> 오답노트는 AI 답변이나 블로그 풀이를 그대로 복사하지 않고, 본인의 언어로 직접 작성해주세요. +> 문제별로 아래 양식을 복사해서 필요한 만큼 반복 작성하시면 됩니다. + +## 문제 1 + +### 문제 정보 + +* 문제명: 거리두기 확인하기 +* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/81302 +* 사용한 알고리즘 / 자료구조: 완전탐색, BFS, 시뮬레이션, 큐, 방문 배열 + +### 처음 접근 방식 + +대기실 크기가 5x5로 작기 때문에, 모든 자리를 확인하면서 응시자가 앉은 자리마다 거리두기 위반이 있는지 검사하면 된다고 생각했다. + +### 풀이 방법 + +1. 각 대기실을 하나씩 확인한다. +2. 대기실의 모든 좌표를 순회하면서 `P`인 위치를 찾는다. +3. `P`를 시작점으로 BFS를 수행하고, 맨해튼 거리 2 이하까지만 탐색한다. +4. 탐색 중 파티션 `X`를 만나면 더 이상 지나가지 않는다. +5. 거리 2 이하에서 다른 `P`를 만나면 해당 대기실은 거리두기를 지키지 않은 것으로 처리한다. +6. 모든 응시자를 확인해도 위반이 없으면 1, 하나라도 위반이 있으면 0을 정답에 추가한다. + +### 어려웠던 지점 + +맨해튼 거리만 보고 단순히 두 사람 사이의 거리를 계산하면, 중간에 파티션이 있는 경우를 제대로 처리하기 어려웠다. + +또 바로 옆, 한 칸 건너, 대각선처럼 경우가 여러 가지라 조건을 직접 나누면 실수하기 쉬웠다. + +### 해결 방법 + +각 응시자 위치에서 BFS를 돌려서 실제로 이동 가능한 빈 테이블을 따라 거리 2 안에 다른 응시자가 있는지만 확인했다. + +탐색 범위를 2칸으로 제한하고 파티션은 지나가지 않도록 하니, 여러 조건을 따로 나누지 않아도 자연스럽게 판별할 수 있었다. + +### 시간복잡도 / 공간복잡도 + +* 시간복잡도: O(P * N^2) +* 공간복잡도: O(N^2) + +`P`는 대기실 수, `N`은 한 대기실의 한 변 길이이다. 실제 문제에서는 대기실이 5개이고 크기가 5x5로 고정되어 있다. + +### 새롭게 알게 된 점 + +조건이 여러 갈래로 나뉘는 격자 문제는 케이스를 직접 외우듯이 처리하기보다, 작은 범위 BFS로 규칙 자체를 구현하면 더 안전하게 풀 수 있다. + +--- + +## 문제 2 + +### 문제 정보 + +* 문제명: [1차] 프렌즈4블록 +* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/17679 +* 사용한 알고리즘 / 자료구조: 시뮬레이션, 완전탐색, 2차원 배열, Set, 반복문 + +### 처음 접근 방식 + +보드를 계속 확인하면서 2x2로 같은 블록이 모인 부분을 찾고, 지운 뒤 위의 블록을 아래로 떨어뜨리는 과정을 반복하면 된다고 생각했다. + +### 풀이 방법 + +1. 문자열 배열로 주어진 board를 수정하기 쉽게 2차원 배열로 바꾼다. +2. 보드 전체를 순회하면서 현재 칸을 왼쪽 위로 하는 2x2 영역을 확인한다. +3. 네 칸이 모두 같은 블록이고 빈 칸이 아니면, 지울 좌표들을 Set에 저장한다. +4. 한 번의 탐색이 끝난 뒤 Set에 있는 좌표들을 빈 칸으로 바꾸고 개수를 더한다. +5. 각 열을 아래에서 위로 확인하면서 남아 있는 블록을 아래쪽부터 다시 채운다. +6. 더 이상 지워질 블록이 없을 때까지 2~5번 과정을 반복한다. +7. 지금까지 지운 블록 개수를 반환한다. + +### 어려웠던 지점 + +같은 블록이 여러 2x2 영역에 겹쳐 포함될 수 있어서, 발견하는 즉시 지워버리면 같은 턴에 함께 지워져야 하는 블록을 놓칠 수 있었다. + +또 블록이 떨어지는 과정에서 행과 열 방향을 헷갈리면 보드가 잘못 갱신되었다. + +### 해결 방법 + +한 라운드에서 지워질 좌표를 먼저 모두 모은 뒤, 탐색이 끝난 후 한꺼번에 지웠다. + +중복 좌표는 Set으로 관리했고, 블록을 내릴 때는 열 단위로 아래에서부터 다시 채우는 방식으로 구현했다. + +### 시간복잡도 / 공간복잡도 + +* 시간복잡도: O(K * M * N) +* 공간복잡도: O(M * N) + +`K`는 블록 제거가 반복되는 횟수, `M`과 `N`은 보드의 세로와 가로 길이이다. + +### 새롭게 알게 된 점 + +시뮬레이션 문제에서는 한 턴 안에서 동시에 일어나는 일과 순차적으로 일어나는 일을 구분해야 한다. 먼저 표시하고 나중에 반영하는 방식이 디버깅하기 좋다. + +--- + +## 문제 3 + +### 문제 정보 + +* 문제명: 기둥과 보 설치 +* 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/60061 +* 사용한 알고리즘 / 자료구조: 시뮬레이션, 구현, 완전탐색, Set, 조건 검사 + +### 처음 접근 방식 + +명령을 순서대로 처리하면서 설치 가능하면 추가하고, 삭제 가능하면 제거하면 된다고 생각했다. 다만 삭제는 주변 구조물이 무너질 수 있으므로 전체 구조가 여전히 유효한지 확인해야 한다고 봤다. + +### 풀이 방법 + +1. 현재 설치된 구조물을 Set이나 배열에 저장한다. +2. 기둥을 설치할 수 있는 조건과 보를 설치할 수 있는 조건을 함수로 분리한다. +3. 설치 명령이면 구조물을 임시로 추가한 뒤, 해당 구조물이 조건을 만족하면 유지한다. +4. 삭제 명령이면 구조물을 임시로 제거한다. +5. 제거 후 남아 있는 모든 기둥과 보가 설치 조건을 만족하는지 검사한다. +6. 하나라도 조건을 만족하지 못하면 삭제를 취소하고 원래 상태로 되돌린다. +7. 모든 명령을 처리한 뒤 x좌표, y좌표, 구조물 종류 순서로 정렬해서 반환한다. + +### 어려웠던 지점 + +기둥과 보의 설치 조건이 서로 연결되어 있어서, 삭제할 때 현재 구조물 하나만 보면 안 되었다. + +특히 보의 양쪽 끝, 기둥 위, 다른 보와의 연결 조건처럼 좌표 기준이 조금씩 달라서 인덱스를 잘못 잡기 쉬웠다. + +### 해결 방법 + +설치 가능 여부를 판단하는 함수를 따로 만들고, 삭제할 때는 일단 지운 뒤 남아 있는 모든 구조물을 다시 검사했다. + +명령 수가 최대 1,000개라서 매번 전체 구조물을 확인해도 시간 안에 충분히 가능했고, 조건 처리가 단순해져서 실수를 줄일 수 있었다. + +### 시간복잡도 / 공간복잡도 + +* 시간복잡도: O(B^2) +* 공간복잡도: O(B) + +`B`는 build_frame의 길이이다. 각 명령마다 현재 구조물을 검사할 수 있으므로 최악의 경우 O(B^2)이다. + +### 새롭게 알게 된 점 + +구현량이 많은 문제에서는 조건을 짧게 줄이는 것보다 검증 함수를 명확히 분리하는 것이 더 중요하다. 삭제처럼 영향 범위가 넓은 작업은 임시 반영 후 전체 검증하는 방식이 안정적이다. + +--- + +# 다음 주 목표 + +* 목표 문제 수: 3 +* 집중할 유형: 완전탐색 / 시뮬레이션 2 +* 세부 키워드: 구현량이 많은 문제, 조건 처리, 디버깅