문제
https://www.acmicpc.net/problem/1012
걸린 시간
01 : 57 : 08 실패
문제
Python3
import sys
class Node():
def __init__(self, v):
self.vertex = v
self.link = None
class listGraph():
def __init__(self):
self.n = 0 # vertex count
self.adj_list = []
# adj_list 의 인덱스를 정점의 번호로 설정
def insert_vertex(self):
self.adj_list.append(None)
self.n += 1
# v값을 u의 인접 리스트에 삽입
def insert_edge(self, u, v):
new = Node(v)
if u > self.n-1 or v > self.n-1:
print("out of area")
else:
new = Node(v)
new.vertex = v
new.link = self.adj_list[u]
self.adj_list[u] = new
def dfs_list(g, v, visited):
visited[v] = True
w = g.adj_list[v]
while w != None:
if not visited[w.vertex]:
dfs_list(g, w.vertex, visited)
w = w.link
def find_connected_component(g, visited):
count = 0
for i in range(0, g.n):
if not visited[i]:
count += 1
dfs_list(g, i, visited)
return count
def adjacency_cabbage(g, u_r, u_c, v_r, v_c, field):
if v_r < 0 or v_c < 0 or v_r > len(field)-1 or v_c > len(field[0])-1:
return
u = field[u_r][u_c] # 현재 배추
v = field[v_r][v_c] # 인접한 배추
# 배추가 심어진 위치이면
if v[0] == 1:
g.insert_edge(u[1], v[1])
if __name__ == "__main__":
sys.setrecursionlimit(3000)
T = int(input())
result = []
for i in range(0, T):
M, N, K = map(int, input().split())
g = listGraph()
cabbage = [list(map(int, input().split())) for _ in range(0, K)]
field = []
# 그래프에 정점 추가
for _ in range(0, K):
g.insert_vertex()
visited = [False for _ in range(0, g.n)]
for i in range(0, N):
tmp = []
for j in range(0, M):
tmp.append([0, None])
field.append(tmp)
for i in range(0, K):
field[cabbage[i][1]][cabbage[i][0]] = [1, i]
for i in range(0, N):
for j in range(0, M):
# 배추가 심어진 위치이면
if field[i][j][0] == 1:
adjacency_cabbage(g, i, j, i, j+1, field) # 상
adjacency_cabbage(g, i, j, i, j-1, field) # 하
adjacency_cabbage(g, i, j, i-1, j, field) # 좌
adjacency_cabbage(g, i, j, i+1, j, field) # 우
result.append(find_connected_component(g, visited))
for i in result:
print(i)
그래프 탐색 방법 dfs, bfs 중 하나를 사용해 연결 성분의 개수를 구하는 문제이다.
입력으로 들어오는 행, 열 값이 가로, 세로의 크기로 주어져 조금 헷갈렸다.
로컬에서는 아무 문제없이 작동했지만 서버에서는 런타임 에러가 발생했다. 원인은 재귀 호출에 있었다. 파이썬에서는 재귀를 무한정 허용할 경우 생길 수 있는 문제들을 고려해 재귀 호출을 1000번으로 제한하고 있다. 노드의 개수가 최대 2500개 까지 있을 수 있는 이번 문제에서는 RecursionError 가 발생할 수 있다.
sys.setrecursionlimit(3000)
위의 문장으로 재귀 호출의 제한을 충분히 늘려주면 런타임 에러가 발생하지 않는다.
TypeScript
const fs = require('fs');
const filePath = process.platform === 'linux' ? '/dev/stdin' : './input';
const stdin = fs.readFileSync(filePath).toString().trim().split('\n').map((s: string) => s.trim());
const input = (() => {
let line = 0;
return () => stdin[line++];
})();
interface Pair{
y: number,
x: number
}
let tc: number = parseInt(input());
const dy: Array<number> = [1, -1, 0, 0];
const dx: Array<number> = [0, 0, -1, 1];
const bfs: Function = (
sy: number
, sx: number
, field: Array<Array<number>>
, visited: Array<Array<boolean>>
, n: number
, m: number
) => {
const queue: Array<Pair> = [{y: sy, x: sx}];
visited[sy][sx] = true;
while(queue.length !== 0){
const size: number = queue.length;
for(let i = 0; i < size; i++){
const y: number = queue[0].y;
const x: number = queue[0].x;
queue.shift();
for(let j = 0; j < 4; j++){
const ny: number = y+dy[j];
const nx: number = x+dx[j];
if(ny < 0 || ny >= n || nx < 0 || nx >= m) continue;
if(!visited[ny][nx] && field[ny][nx]){
visited[ny][nx] = true;
queue.push({y: ny, x: nx});
}
}
}
}
}
while(tc--){
const [m, n, k] = input().split(' ').map(Number);
const field: Array<Array<number>> = Array.from(Array(n), () => Array(m).fill(0));
const visited: Array<Array<boolean>> = Array.from(Array(n), () => Array(m).fill(false));
for(let i = 0; i < k; i++){
const [x, y] = input().split(' ').map(Number);
field[y][x] = 1;
}
let ans = 0;
for(let r = 0; r < n; r++){
for(let c = 0; c < m; c++){
if(field[r][c] && !visited[r][c]){
bfs(r, c, field, visited, n, m);
ans++;
}
}
}
console.log(ans);
}
shift() 만을 이용해 원소를 빼내어 사용하면 TypeScript 에서는 undefined 도 반환되는 값 중의 하나이기 때문에 에러가 발생한다.
맨 앞의 값을 참조한 뒤 shift() 로 값을 제거해주는 방법을 사용해서 해결했다.
참고
'Baekjoon' 카테고리의 다른 글
Baekjoon 1931번 회의실배정 (0) | 2020.08.07 |
---|---|
Baekjoon 2606번 바이러스 (0) | 2020.08.06 |
Baekjoon 1927번 최소 힙 (0) | 2020.08.04 |
Baekjoon 11279번 최대 힙 (0) | 2020.08.04 |
Baekjoon 2630번 색종이 만들기 (0) | 2020.08.02 |
댓글