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
163 changes: 163 additions & 0 deletions studies/week-01/min9u/1767-프로세서연결하기.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# [SWEA 1767] 프로세서 연결하기

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

---

## 1. 접근 방법

N×N 격자에서 값이 1인 칸이 '코어'이며, 이 중 가장자리(0행/0열/N-1행/N-1열)에 붙어 있는 코어는 이미 전원과 연결된 것으로 간주해 탐색 대상에서 제외한다. 나머지 코어들을 리스트로 모은 뒤, 각 코어마다

Comment on lines +15 to +16

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

경계 코어 제외 조건을 문서와 코드에 일관되게 적용하세요.

문서는 경계 코어를 제외한다고 설명하지만, 구현은 모든 코어를 DFS에 넣어 불필요한 방향 분기를 생성합니다.

  • studies/week-01/min9u/1767-프로세서연결하기.md#L15-L16: 접근 설명과 실제 구현의 조건을 일치시키세요.
  • studies/week-01/min9u/1767-프로세서연결하기.md#L52-L56: 0 < i < n - 1 and 0 < j < n - 1 조건으로 내부 코어만 수집하세요.

As per path instructions, studies/**/*.md에서는 문서와 실제 코드의 로직 일치 여부 및 최대 입력의 성능 위험을 검증해야 합니다.

📍 Affects 1 file
  • studies/week-01/min9u/1767-프로세서연결하기.md#L15-L16 (this comment)
  • studies/week-01/min9u/1767-프로세서연결하기.md#L52-L56
🤖 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/min9u/1767-프로세서연결하기.md` around lines 15 - 16, 경계 코어 제외 조건이
설명과 구현에서 일치하도록 수정하세요. studies/week-01/min9u/1767-프로세서연결하기.md의 15-16행 설명은 내부 코어만
탐색 대상으로 삼는 동작을 명확히 유지하고, 52-56행의 코어 수집 로직은 0 < i < n - 1 및 0 < j < n - 1 조건을 적용해
내부 코어만 리스트에 추가하도록 변경하세요.

Source: Path instructions

- 상 / 하 / 좌 / 우 네 방향 중 전선을 그을 수 있는(경로상에 다른 코어·전선이 없는) 방향으로 연결을 시도
- 혹은 아무 방향으로도 연결하지 않음

의 선택지를 두고 DFS(백트래킹)로 모든 경우를 탐색한다. 방향을 선택해 전선을 그으면 해당 경로를 임시로 1로 채워 이후 탐색에서 장애물로 작동하게 하고, 재귀에서 돌아올 때 다시 0으로 복원(백트래킹)한다.

모든 코어에 대한 선택이 끝나면(리스트 끝에 도달하면) 그 순간의 "연결된 코어 수(core)"와 "전선 길이 합(score)"을 이용해 전역 최적값을 갱신한다. 이때 목표는 **연결된 코어 수를 최대화**하는 것이 1순위, 그 중에서 **전선 길이 합을 최소화**하는 것이 2순위임에 유의해야 한다.

## 2. 시간 복잡도

**O(5^K × N)** — K는 가장자리가 아닌 코어의 개수(문제 제약상 N ≤ 12이므로 K도 그리 크지 않음), 5는 각 코어마다 "상/하/좌/우로 연결" 4가지 + "연결 안 함" 1가지의 선택지 수. 각 선택마다 해당 방향으로 장애물이 있는지 확인하고 그 경로를 채우고/비우는 데 O(N)이 걸리므로 여기에 N을 곱한다. 최악의 경우 5^K가 매우 커 보이지만, 실제로는 이미 막힌 방향은 가지치기되므로 체감 시간은 이보다 훨씬 짧다.
Comment on lines +24 to +26

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

🧩 Analysis chain

🏁 Script executed:

sed -n '1,220p' studies/week-01/min9u/1767-프로세서연결하기.md

Repository: DevJunz/coding-test-study-template

Length of output: 5543


🌐 Web query:

SWEA 1767 프로세서 연결하기 constraints core count N <= 12 maximum cores

💡 Result:

The constraints for the SW Expert Academy (SWEA) problem 1767, "Processor Connection" (프로세서 연결하기), are as follows: - Grid Size (N): 7 <= N <= 12 [1][2][3] - Number of Cores: The number of cores is between 1 and 12 [1][3]. The goal of the problem is to connect as many cores as possible to the power source located at the edge of the grid [4][5]. When multiple ways exist to connect the maximum number of cores, the solution must choose the one with the minimum total wire length [3][5]. Cores already located on the edge are considered connected to the power source by default [4][6][5].

Citations:


시간 복잡도 표기를 코드에 맞게 고치세요.
지금 구현은 cores에 가장자리 코어까지 모두 넣어서 DFS를 돌리므로, 실제 깊이는 내부 코어 K가 아니라 전체 코어 수 C = len(cores)입니다. 따라서 이 코드의 최악 복잡도는 O(5^C × N)이고, 설명처럼 N ≤ 12라서 K가 작다는 근거도 맞지 않습니다. 문제의 코어 수 상한은 12이므로, 최악 입력 기준 TLE 위험도 같이 적고 남은 코어 수로 상한 가지치기 같은 pruning을 덧붙이는 게 좋습니다.

🤖 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/min9u/1767-프로세서연결하기.md` around lines 24 - 26, 시간 복잡도 설명을 DFS
구현의 실제 대상인 전체 코어 수 C = len(cores)에 맞춰 O(5^C × N)으로 수정하세요. 가장자리 코어도 cores에 포함되어
처리된다는 점을 반영하고, N ≤ 12를 근거로 내부 코어 K가 작다고 설명하지 마세요. 코어 수 상한 12에서 최악의 경우 TLE 위험을
명시하고, 가능하면 남은 코어 수를 이용한 상한 가지치기 적용도 설명에 추가하세요.

Source: Path instructions


## 3. 공간 복잡도

**O(N²)** — 코어/전선 상태를 저장하는 tile 2차원 배열이 N×N 크기이며, 코어 좌표 리스트(cores)는 최대 N² 개까지 저장될 수 있으나 실제로는 그보다 훨씬 작다. 재귀 호출 스택의 깊이는 O(K) 수준으로 N²에 비해 무시할 만하다.
Comment on lines +28 to +30

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 | 🟡 Minor | ⚡ Quick win

공간 복잡도의 근거를 정확히 표현하세요.

tileO(N²), cores와 재귀 스택은 각각 O(K)이므로 전체는 O(N² + K) = O(N²)입니다. 최종 결론은 맞지만, 현재 코드 기준 KO(N²)일 수 있으므로 재귀 스택을 “무시할 만하다”고 설명하는 것은 부정확합니다.

As per path instructions, studies/**/*.md에서는 공간 복잡도를 실제 자료구조와 재귀 깊이 기준으로 검증해야 합니다.

🤖 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/min9u/1767-프로세서연결하기.md` around lines 28 - 30, 공간 복잡도 절의 근거를
실제 자료구조 기준으로 수정하세요. tile은 O(N²), cores와 재귀 호출 스택은 각각 O(K)로 명시하고, 전체 공간 복잡도를 O(N²
+ K) = O(N²)로 정리하세요. K가 O(N²)일 수 있으므로 재귀 스택을 무시할 수 있다는 설명은 제거하세요.

Source: Path instructions


## 4. 핵심 풀이 방법 ⭐

- **"최대한 많이 연결"이 최우선 조건**이라는 점이 핵심. 즉 모든 코어가 다 연결되지 않아도 되고, 연결된 코어 수가 최대인 경우들 중에서만 전선 길이의 최솟값을 비교해야 한다. (문제 조건을 꼼꼼히 읽지 않으면 "모든 코어를 반드시 연결해야 한다"고 착각하기 쉬움 — 실제로 헤맸던 지점.)
- 각 코어에서 방향을 정할 때, 단순히 "빈 칸인지"가 아니라 **경로 전체에 코어나 다른 전선이 없는지**를 끝까지 확인해야 한다(중간에 하나라도 걸리면 그 방향은 불가능).
- 전선을 그은 뒤 탐색이 끝나면 반드시 원상복구(백트래킹)해야 다른 코어의 방향 선택에 영향을 주지 않는다. `tile` 배열을 실제로 채우고 비우는 방식으로 "장애물 검사"를 재사용한 것이 포인트.
- 전역 변수(`idx, score, min_score, core, max_core`)로 상태를 관리하며, 매 DFS 호출 시작 지점에서 "지금까지 연결된 코어 수 = 지금까지의 최댓값"이면 점수 갱신, "지금까지 연결된 코어 수 > 지금까지의 최댓값"이면 최댓값과 최소 점수를 함께 갱신하는 방식으로 1순위(최대 연결 수)·2순위(최소 전선 길이) 조건을 동시에 처리한다.
- 5가지 선택지(4방향 + 미연결) 모두를 매번 시도해야 하는 완전탐색이므로, 가능한 방향이 아닐 경우 조기에 걸러내는 것이 성능에 중요하다.

## 5. 실제 코드

```python
'''
헤맸던 포인트 : "최대한 많은 코어"에 전원을 연결하였을 경우, 전설 길이의 합이 최소가 되는 값을 구하라
코어가 다 연결되지 않는 경우를 생각하지 않았음. 문제 조건을 더 자세히 살펴볼것
'''
Comment on lines +44 to +46

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

회고 주석의 오타를 수정하세요.

전설 길이전선 길이로 고쳐야 문서 의미가 정확합니다.

As per path instructions, 사용자에게 보이는 문서의 문장 품질과 가독성도 점검해야 합니다.

🤖 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/min9u/1767-프로세서연결하기.md` around lines 44 - 46, 회고 주석의 “전설 길이”
오타를 “전선 길이”로 수정하고, 해당 문장이 자연스럽고 읽기 쉽게 유지되는지 확인하세요.

Source: Path instructions

T = int(input())
for tc in range(T):
n = int(input())
tile = [list(map(int, input().split())) for _ in range(n)]

cores = []
for i in range(n):
for j in range(n):
if tile[i][j] == 1:
cores.append((i,j))

idx = 0
score = 0
min_score = float('inf')
core = 0 # 총 전원이 연결된 코어 개수
max_core = 0 # 지금까지 가장 많이 연결된 코어 개수


def dfs():
global idx, score, min_score, max_core, core
if core==max_core:
min_score = min(min_score, score)
if core>max_core:
min_score = score
max_core = core
if idx == len(cores):
return
Comment on lines +65 to +73

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='studies/week-01/min9u/1767-프로세서연결하기.md'

# 기본 구조와 코드 위치 확인
wc -l "$file"
rg -n "def dfs|max_core|min_score|core|시간 복잡도|공간 복잡도|접근|핵심 풀이|실제 코드" "$file"

# 관련 구간만 번호와 함께 확인
sed -n '1,220p' "$file" | cat -n

Repository: DevJunz/coding-test-study-template

Length of output: 8278


남은 코어 수 상한으로 DFS를 가지치기하세요.
core + (len(cores) - idx) < max_core 인 가지는 남은 코어를 전부 연결해도 현재 최댓값을 넘지 못하므로 바로 반환하면 됩니다. 같은 max_core를 만들 수 있는 가지는 남겨 둬야 전선 길이 최소값 비교가 유지됩니다.

수정안
         if idx == len(cores):
             return
+        if core + (len(cores) - idx) < max_core:
+            return
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def dfs():
global idx, score, min_score, max_core, core
if core==max_core:
min_score = min(min_score, score)
if core>max_core:
min_score = score
max_core = core
if idx == len(cores):
return
def dfs():
global idx, score, min_score, max_core, core
if core==max_core:
min_score = min(min_score, score)
if core>max_core:
min_score = score
max_core = core
if idx == len(cores):
return
if core + (len(cores) - idx) < max_core:
return
🤖 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/min9u/1767-프로세서연결하기.md` around lines 65 - 73, Update the DFS
function to return immediately when core + (len(cores) - idx) < max_core,
placing this upper-bound pruning before deeper exploration. Use a strict
less-than comparison so branches that can still tie max_core remain available
for min_score comparison.

Source: Path instructions

y,x = cores[idx]
# 상하좌우 각 방향에서 연결이 가능한지 확인 후 dfs
# 상
go_up = True
for i in range(0,y):
if tile[i][x] == 1:
go_up = False
break
if go_up:
for i in range(0,y):
tile[i][x] = 1
idx += 1
score += y
core+=1
dfs()
core-=1
score -= y
idx -= 1
for i in range(0,y):
tile[i][x] = 0
# 하
go_down = True
for i in range(y+1,n):
if tile[i][x] == 1:
go_down = False
break
if go_down:
for i in range(y+1,n):
tile[i][x] = 1
idx+=1
score+=n-y-1
core+=1
dfs()
core-=1
score-=n-y-1
idx-=1
for i in range(y+1,n):
tile[i][x] = 0
#좌
go_left = True
for j in range(0,x):
if tile[y][j] == 1:
go_left = False
break
if go_left:
for j in range(0,x):
tile[y][j] = 1
idx+=1
score+=x
core+=1
dfs()
core-=1
score-=x
idx-=1
for j in range(0,x):
tile[y][j] = 0
#우
go_right = True
for j in range(x+1,n):
if tile[y][j] == 1:
go_right = False
break
if go_right:
for j in range(x+1,n):
tile[y][j] = 1
idx+=1
score+=n-x-1
core+=1
dfs()
core-=1
score-=n-x-1
idx-=1
for j in range(x+1,n):
tile[y][j] = 0
# 연결하지 않음
idx+=1
dfs()
idx-=1
return

dfs()
print(f'#{tc+1} {min_score}')
```

---

### 🧠 회고 (선택)

- 문제의 핵심 조건(코어가 전원에 가장 많이 연결될 경우)을 잘못 오해하여 코어에 모든 전원이 연결될 경우로 문제를 풀었음. 문제의 조건을 문제풀이 전에 잘 정리하는 습관을 길러야겠다.
<!-- 배운 점, 비슷한 유형에서 재사용할 아이디어, 리뷰어에게 묻고 싶은 점 -->
Loading