일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ★
- dp
- dfs
- BFS
- ☆
- 백준9단계
- 알고리즘공부
- 무료코딩강의
- 백준알고리즘
- 자바
- 무료개발강의
- 자바개념
- 백준단계별로풀어보기
- 브루트포스
- 백준자바
- 동적계획법
- 자바의정석연습문제풀이
- 코딩공부
- java
- 백트래킹
- 자바의정석
- Java개념
- 알고리즘
- 다이나믹 프로그래밍
- 자바의정석연습문제
- 개발공부
- 자바공부
- 백준
- 시간 복잡도
- 빅오 표기법
- Today
- Total
더 많이 실패하기
공부 203일차: 백준 1261번 알고스팟 자바 java 본문
1261 알고스팟
https://www.acmicpc.net/problem/1261
1261번: 알고스팟
첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미
www.acmicpc.net
백준 1261번 문제 알고스팟
문제
시간 제한 | 메모리 제한 | 제출 | 정답 | 맞힌 사람 | 정답 비율 |
---|---|---|---|---|---|
1 초 (추가 시간 없음) | 128 MB | 32738 | 14014 | 9530 | 41.875% |
문제
알고스팟 운영진이 모두 미로에 갇혔다. 미로는 N*M 크기이며, 총 1*1크기의 방으로 이루어져 있다. 미로는 빈 방 또는 벽으로 이루어져 있고, 빈 방은 자유롭게 다닐 수 있지만, 벽은 부수지 않으면 이동할 수 없다.
알고스팟 운영진은 여러명이지만, 항상 모두 같은 방에 있어야 한다. 즉, 여러 명이 다른 방에 있을 수는 없다. 어떤 방에서 이동할 수 있는 방은 상하좌우로 인접한 빈 방이다. 즉, 현재 운영진이 (x, y)에 있을 때, 이동할 수 있는 방은 (x+1, y), (x, y+1), (x-1, y), (x, y-1) 이다. 단, 미로의 밖으로 이동 할 수는 없다.
벽은 평소에는 이동할 수 없지만, 알고스팟의 무기 AOJ를 이용해 벽을 부수어 버릴 수 있다. 벽을 부수면, 빈 방과 동일한 방으로 변한다.
만약 이 문제가 알고스팟에 있다면, 운영진들은 궁극의 무기 sudo를 이용해 벽을 한 번에 다 없애버릴 수 있지만, 안타깝게도 이 문제는 Baekjoon Online Judge에 수록되어 있기 때문에, sudo를 사용할 수 없다.
현재 (1, 1)에 있는 알고스팟 운영진이 (N, M)으로 이동하려면 벽을 최소 몇 개 부수어야 하는지 구하는 프로그램을 작성하시오.
입력
첫째 줄에 미로의 크기를 나타내는 가로 크기 M, 세로 크기 N (1 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 미로의 상태를 나타내는 숫자 0과 1이 주어진다. 0은 빈 방을 의미하고, 1은 벽을 의미한다.
(1, 1)과 (N, M)은 항상 뚫려있다.
출력
첫째 줄에 알고스팟 운영진이 (N, M)으로 이동하기 위해 벽을 최소 몇 개 부수어야 하는지 출력한다.
예제 입력 1
3 3
011
111
110
예제 출력 1
3
예제 입력 2
4 2
0001
1000
예제 출력 2
0
예제 입력 3
6 6
001111
010000
001111
110001
011010
100010
예제 출력 3
2
과정 생각해보기 & 오답
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static int min = Integer.MAX_VALUE;
static int[][] matrix;
static boolean[][] visited;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
matrix = new int[m][n];
visited = new boolean[m][n];
for(int i = 0; i < m; i++) {
String str = br.readLine();
for(int j = 0; j < n; j++) {
matrix[i][j] = str.charAt(j)-'0';
}
}
bfs();
System.out.println(min);
}
static void bfs() {
Queue<Point> q = new LinkedList<>();
q.add(new Point(0, 0, 0)); // (1,1)자리에서 시작
while(!q.isEmpty()) {
Point now = q.poll();
visited[now.x][now.y] = true;
if(now.x == m-1 && now.y == n-1) {
min = Math.min(min, now.count);
}
for(int i = 0; i < 4; i++) { // 상하좌우
int X = now.x + dx[i];
int Y = now.y + dy[i];
if(X < 0 || X > m-1 || Y < 0 || Y > n-1) {
continue;
}
if(!visited[X][Y] && matrix[X][Y] == 0) { // 그냥 넘어갈 수 있음
q.add(new Point(X, Y, now.count));
}
if(!visited[X][Y] && matrix[X][Y] == 1) { // 벽 -> 뚫어야 함
q.add(new Point(X, Y, now.count+1));
}
}
}
}
static class Point{
int x;
int y;
int count;
Point(int x, int y, int count){
this.x = x;
this.y = y;
this.count = count;
}
}
}
|
cs |
메모리 초과가 뜬 코드
이 문제처럼 조건을 줘서 끊어보려고 했는데, 그러면 최소값 갱신이 되지 않았다
그래서 검색해보니 일반 Queue를 사용하면 안 되고, 우선순위큐를 써야 한다고 한다
하지만.. 난 덱을 썼다..
이 블로그에 매우 상세하게 설명되어 있음!
요약하자면 양쪽으로 데이터를 넣을 수 있는 덱을 이용해서 앞으로 넣는 게 우선순위인지, 뒤로 넣는 게 우선순위인지 알려주는 것이다
벽보다 벽이 없는 쪽을 먼저 가는 것이 최소값을 만족하므로, 이쪽을 우선순위로 둔디
정답 인정 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static int[][] matrix;
static boolean[][] visited;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
matrix = new int[m][n];
visited = new boolean[m][n];
for(int i = 0; i < m; i++) {
String str = br.readLine();
for(int j = 0; j < n; j++) {
matrix[i][j] = str.charAt(j)-'0';
}
}
bfs();
}
static void bfs() {
Deque<Point> deque = new LinkedList<>();
deque.addLast(new Point(0, 0, 0)); // (1,1)자리에서 시작
visited[0][0] = true;
while(!deque.isEmpty()) {
Point now = deque.pollLast();
// visited[now.x][now.y] = true; // 순서가 달라지는 등 필요할 때 아니면 쓰지 않기
if(now.x == m-1 && now.y == n-1) {
System.out.println(now.count);
return; // 덱으로 우선순위를 설정했으므로 min 변수를 설정할 것 없이 바로 끝내면 된다
}
for(int i = 0; i < 4; i++) { // 상하좌우
int X = now.x + dx[i];
int Y = now.y + dy[i];
if(X < 0 || X > m-1 || Y < 0 || Y > n-1) {
continue;
}
if(!visited[X][Y] && matrix[X][Y] == 0) { // 그냥 넘어갈 수 있음
visited[X][Y] = true;
deque.addLast(new Point(X, Y, now.count));
}
if(!visited[X][Y] && matrix[X][Y] == 1) { // 벽 -> 뚫어야 함
visited[X][Y] = true;
deque.addFirst(new Point(X, Y, now.count+1));
}
}
}
}
static class Point{
int x;
int y;
int count;
Point(int x, int y, int count){
this.x = x;
this.y = y;
this.count = count;
}
}
}
|
cs |
코드 짜다가 메모리 관련 문제와 부딪치면 많이 어렵다..
'알고리즘 > 백준' 카테고리의 다른 글
공부 205일차: 백준 11725번 트리의 부모 찾기 자바 java (0) | 2023.02.20 |
---|---|
공부 204일차: 백준 1991번 트리 순회 자바 java (0) | 2023.02.19 |
공부 202일차: 백준 13549번 숨바꼭질 3 자바 java (0) | 2023.02.17 |
공부 201일차: 백준 14226번 이모티콘 자바 java (0) | 2023.02.16 |
공부 200일차: 백준 13913번 숨바꼭질 4 자바 java (0) | 2023.02.15 |