시리즈: 알고리즘 (32개 글)
- 자바로 알고리즘 풀기
- [Java] 백준 10431 - 줄 세우기
- [Java & Node.js] 백준 9935 - 문자열 폭발
- [Node.js] 백준 22866 - 탑 보기
- [Java] 백준 4485 - 녹색 옷 입은 애가 젤다지?
- [Node.js] 백준 1283 - 단축키 지정
- [Java & Node.js] 백준 14469 - 소가 길을 건너간 이유 3
- [Java] 백준 8979 - 올림픽
- [Node.js] 백준 22866 - 탑 보기
- [Java] 백준 7568 - 덩치
- [Java] 백준 1244 - 스위치 켜고 끄기
- [Node.js] 백준 19941 - 햄버거 분배
- [Node.js] 백준 1254 - 팰린드롬 만들기
- [Java] 백준 2589 - 보물섬
- [Java] 백준 2309 - 일곱 난쟁이
- [Java] 백준 1789 - 수들의 합
- [Java] 백준 1987 - 알파벳
- [Node.js] [Rust] 백준 24460 - 특별상이라도 받고 싶어
- [Node.js] 백준 7576 - 탑 보기
- [Rust] 백준 1047 - 울타리 (N^4 브루트포스 + 그리디)
- [Node.js] 백준 9657 - 돌게임3
- [Rust] 백준 4963 - 섬의 개수
- [Node.js] 프로그래머스 - 모의고사 / 실패율
- [Rust] 백준 2667 - 단지번호붙이기
- [Node.js] 프로그래머스 - 방문 길이
- [Node.js] 프로그래머스 - 괄호 회전하기
- [Rust] 백준 1002 - 터렛
- [Node.js] 프로그래머스 - 크레인 인형뽑기 게임
- [Node.js] 프로그래머스 - 기능개발
- [Rust] 백준 13717 - 포켓몬 GO
- [JavaScript] 백준 1092 - 배
- [Rust] 백준 25329 - 학생별 통화 요금 계산
들어가기 전
- 0 : 길이 없는 빈 공간
- 1 : 탐색 시작 가능 지점
- 2 : 이미 탐색한 집
이렇게 처리하기로 생각했다.
접근
- 단지를 bfs 로 탐색하고 방문한 부분은 표시한다.
- bfs가 끝나면, 탐색 횟수를 반환해 저장해둔다.
- 저장해둔 길이를 먼저 출력한다
- 이후 정렬된 각 요소를 출력한다.
접근 자체는 쉬웠는데.
정답 코드
use std::{
collections::VecDeque,
io::{self, BufWriter, Read, Write},
};
pub fn main() {
let mut input = String::new();
io::stdin()
.read_to_string(&mut input)
.expect("input expected");
let mut lines = input.lines();
let n: usize = lines.next().expect("N expected").trim().parse().unwrap();
let mut apt_map: Vec<Vec<usize>> = Vec::new();
for _ in 0..n {
let line_str = lines.next().expect("apt Line expected");
let apt_line: Vec<usize> = line_str
.trim()
.chars()
.filter_map(|c| c.to_digit(10))
.map(|d| d as usize)
.collect();
apt_map.push(apt_line);
}
let mut complexes: Vec<usize> = Vec::new();
// bfs 호출
for r in 0..n {
for c in 0..n {
if apt_map[r][c] == 1 {
let complex_len = bfs(&mut apt_map, r as isize, c as isize, n as isize);
complexes.push(complex_len);
}
}
}
complexes.sort();
let mut ans_buf = BufWriter::new(io::stdout().lock());
let len_ans = complexes.len();
writeln!(ans_buf, "{}", len_ans).expect("write failed");
for i in 0..len_ans {
writeln!(ans_buf, "{}", complexes[i]).expect("complex line write failed");
}
ans_buf.flush().expect("flush failed");
}
fn bfs(apt_map: &mut Vec<Vec<usize>>, start_r: isize, start_c: isize, n: isize) -> usize {
let mut complex_len = 0;
let mut queue: VecDeque<(isize, isize)> = VecDeque::new();
const DR: [isize; 4] = [1, -1, 0, 0];
const DC: [isize; 4] = [0, 0, -1, 1];
complex_len += 1;
queue.push_back((start_r, start_c));
apt_map[start_r as usize][start_c as usize] = 2;
while let Some((r, c)) = queue.pop_front() {
for i in 0..4 {
let nr = r + DR[i];
let nc = c + DC[i];
if nr < 0 || nr >= n || nc < 0 || nc >= n {
continue;
}
let nr_usize = nr as usize;
let nc_usize = nc as usize;
if apt_map[nr_usize][nc_usize] == 1 {
complex_len += 1;
apt_map[nr_usize][nc_usize] = 2;
queue.push_back((nr, nc));
}
}
}
complex_len
}
마무리
IO 쪽이랑, 갱신 로직을 한 번 누락하는 바람에 많이 틀렸던 문제
차근차근 개선해나가야 했던 문제!
사실 uszie 와 isize 를 오가는 것도 귀찮은데…
좋은 방법 없을까..?
trim()은 소중하다. 잘 기억하자.
- 배열 인덱스 :
usize - 좌표 계산 : (음수 가능성) ->
isize
캐스팅하여 사용하자.
