Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions studies/week-01/yeseolee/1767-프로세서 연결하기.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# [SWEA 1767] 프로세서 연결하기

| 항목 | 내용 |
|:---|:---|
| 🔗 문제 | https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV4suNtaXFEDFAUf |
| 📚 주제 | 백트래킹 |
| 🎚️ 난이도 | D4 |
| ⏱️ 소요 시간 | 2h |
| 🔁 다시 풀기 | 예 |

---

## 1. 접근 방법
<!-- 문제를 어떻게 이해했고, 왜 이 전략을 택했는지. 처음 떠올린 방법과 막혔던 지점도 좋음. -->
백트래킹 문제라는 것을 파악하고 풀었다.
경계 제거를 잘못 작성하여, 시간 초과가 발생했다.
AI를 통해 정답 코드를 확인했다.

```
# 잘못 작성한 코드
for i in range(1, n):
for j in range(1, n):
if board[i][j] == 1:
cores.append((i, j))
```
Comment on lines +19 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

코드 펜스에 Python 언어 태그를 추가해 주세요.

정적 분석의 MD040 경고처럼 해당 블록은 Python 코드이므로 ```python으로 시작해야 문서 렌더링과 문법 하이라이팅이 일관됩니다.

수정 예시
-```
+```python
 # 잘못 작성한 코드
 for i in range(1, n):
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 19-19: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@studies/week-01/yeseolee/1767-프로세서` 연결하기.md around lines 19 - 25, 코드 블록에
Python 언어 태그가 누락되어 있습니다. 해당 코드 펜스의 시작 부분을 ```python으로 변경해 Python 문법 하이라이팅과 MD040
검사를 충족하세요.

Sources: Path instructions, Linters/SAST tools


## 2. 시간 복잡도
<!-- 예: O(N log N) — 정렬 O(N log N) + 순회 O(N). 근거를 함께 적기. -->
<!-- SWEA는 시간 제한이 빡빡한 문제가 많으니 반드시 따져볼 것! -->
코어 수는 (7 ≤ N ≤ 12)이고, 각 코어는 상/하/좌/우/미포함 5가지 경우의 수를 가진다.
경계에 코어가 없을 경우, 최악의 경우 5^N 이나 그런 케이스에서는 시간 초과가 발생한다.

**O( )** —

## 3. 공간 복잡도
<!-- 예: O(N) — 방문 배열 N개. -->
O(N^2) board 크기 이상을 요구하지 않는다.

**O( )** —
Comment on lines +30 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

복잡도 표기를 실제 구현과 맞추고, 중복 탐색을 제거해야 합니다.

N은 보드 한 변의 크기이고, 후보 코어 수는 M = len(cores)로 분리해서 계산해야 합니다. 현재 backtracking()idx 이후의 모든 코어를 다시 순회하면서 각 코어에 대해 연결 4가지와 미연결 1가지를 재귀 호출합니다. 따라서 호출 수는 최악의 경우 Θ(6^M), 각 방향의 경로 확인이 O(N)이므로 현재 시간 복잡도는 O(N·6^M)입니다. 문서의 O( )5^N 표기는 모두 실제 코드와 맞지 않습니다.

각 재귀 호출에서 코어 하나만 처리하도록 바꾸면 O(N·5^M)이 되고, cnt + (M - idx) < answer[0] 가지치기도 추가할 수 있습니다. 공간 복잡도는 board O(N²), 코어 목록·재귀 스택 O(M), 활성 path 목록 최대 O(MN)을 합쳐 O(N² + MN + M)입니다.

권장 DFS 구조
 def backtracking(idx, cnt, length):
     nonlocal answer
-    if answer[0] < cnt or (answer[0] == cnt and answer[1] > length):
-        answer = [cnt, length]
+    if idx == len(cores):
+        if answer[0] < cnt or (answer[0] == cnt and answer[1] > length):
+            answer = [cnt, length]
+        return
+
+    if cnt + len(cores) - idx < answer[0]:
+        return

-    for i in range(idx, len(cores)):
-        x, y = cores[i]
+    x, y = cores[idx]
+    for d in range(4):
         ...
-        backtracking(i + 1, cnt + 1, length + len(path))
+        backtracking(idx + 1, cnt + 1, length + len(path))
         ...
-    backtracking(i + 1, cnt, length)
+    backtracking(idx + 1, cnt, length)

Also applies to: 63-88

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@studies/week-01/yeseolee/1767-프로세서` 연결하기.md around lines 30 - 39,
backtracking()이 idx 이후 코어를 다시 순회하지 않고 현재 idx의 코어 하나만 처리하도록 수정해 중복 탐색을 제거하고, 연결
4방향과 미연결 1경우만 재귀 호출하게 하세요. 필요하면 cnt + (M - idx) < answer[0] 가지치기를 추가하고, 문서의 시간
복잡도를 M=len(cores) 기준 O(N·5^M), 공간 복잡도를 O(N² + MN + M)으로 갱신하세요.

Source: Path instructions


## 4. 핵심 풀이 방법 ⭐
<!-- 이 문제의 결정적 아이디어 / 자주 하는 실수 / 알아야 할 개념. 가장 중요한 항목! -->
1. 백트래킹
2. 가장 자리에 있는 core는 이미 연결된 상태 (제거하지 않으면 시간 초과)


## 5. 실제 코드
<!-- 통과한 코드. 언어 태그를 정확히 표기하세요. -->

```python
def solution(n, board):
cores = []
for i in range(n):
for j in range(n):
if board[i][j] == 1:
if i == 0 or i == n - 1 or j == 0 or j == n - 1:
continue
cores.append((i, j))

answer = [0, float("inf")]
dx, dy = [1, -1, 0, 0], [0, 0, -1, 1]

def backtracking(idx, cnt, length):
nonlocal answer
if answer[0] < cnt or (answer[0] == cnt and answer[1] > length):
answer = [cnt, length]

for i in range(idx, len(cores)):
# 전선-상,하,좌,우
x, y = cores[i]
for d in range(4):
possible = True
path = []
nx, ny = x + dx[d], y + dy[d]
while 0 <= nx < n and 0 <= ny < n:
if board[nx][ny] != 0:
possible = False
break
path.append((nx, ny))
nx, ny = nx + dx[d], ny + dy[d]
if possible:
for nx, ny in path:
board[nx][ny] = -1
backtracking(i + 1, cnt + 1, length + len(path))
for nx, ny in path:
board[nx][ny] = 0
# 전선 X
backtracking(i + 1, cnt, length)

backtracking(0, 0, 0)
return answer[1]


T = int(input())
for test_case in range(1, T + 1):
N = int(input())
board = [list(map(int, input().split())) for _ in range(N)]
answer = solution(N, board)
print(f"#{test_case} {answer}")
```

---

### 🧠 회고 (선택)
<!-- 배운 점, 비슷한 유형에서 재사용할 아이디어, 리뷰어에게 묻고 싶은 점 -->
시간초과를 발생하지 않기 위해서는 경계에 있는 코어는 제외하는 것이 가장 중요하다.
추가로 `answer`를 갱신할 수 없는 경우는 가지치기를 통해 `backtracking`을 최적화 할 수 있다.
Loading