728x90
🟩 4번. 미로의 최단거리 통로 | BFS
- 레벨 탐색 문제이다.
- 출발지점 (0, 0)에서 도착점 (6,6) 까지 갈 건데 갈 때마다 lv++처리하여 dist 배열에 해당 방문한 lv들을 담아가며 처리하면 된다.
- 4방향 탐색할 때 변수 주의해서 사용할 것
package to_0818_2;
//미로의 최단거리 통로
import java.util.*;
class Solution {
static int[][] dist;//거리용
//4방향
static int[] dx = {0, 0, 1, -1};
static int[] dy = {1, -1, 0, 0};
public int solution(int[][] board){
//초기화
dist = new int[7][7];
Queue<int[]> Q = new LinkedList<>();
Q.add(new int[] {0, 0});//시작점 처리
board[0][0] = 1;//방문체크
int lv= 0;
while(!Q.isEmpty()){
int len = Q.size();
lv++;
for(int i=0 ;i<len ;i++) {
int[] cur = Q.poll();
for(int j=0; j<4; j++) {
//여기서 dx인덱스 찍을 때 변수 잘 보고 찍기
int nx = cur[0] + dx[j];
int ny = cur[1] + dy[j];
if(nx < 0 || ny <0 || nx >=7 || ny >=7) continue;
if(board[nx][ny] == 0) {
board[nx][ny] = 1;
Q.add(new int[] {nx, ny});
dist[nx][ny] = lv;
}
}
}
}
if(dist[6][6] > 0) return dist[6][6];
return -1;
}
public static void main(String[] args){
Solution T = new Solution();
int[][] arr={{0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 1, 0, 0, 0},
{1, 1, 0, 1, 0, 1, 1},
{1, 1, 0, 1, 0, 0, 0},
{1, 0, 0, 0, 1, 0, 0},
{1, 0, 1, 0, 0, 0, 0}};
System.out.println(T.solution(arr));
}
}
🟩 5번. 집을 짓자
풀이
- 각각의 빌딩 1에서 출발하여 모든 빌딩에서 최단거리로 닿는 빈 땅까지의 거리합을 구해야 한다.
- 만약 모든 빌딩 중 하나라도 닿지 않는 빌딩이 있다면 -1 리턴해야 하는 점에 주의
- 체크 배열을 따로 쓰지는 않는다.
- 1인 빌딩값들을 출발점으로 삼기 위해 Q에 담아둘 건데, emptyLand 변수에 처음에는 0으로 초기화하여 board값이 emptyLand변수와 일치할 때만 탐색을 할 것이다. 탐색 완료한 뒤 emptyLand- - 처리
- 이렇게 해야 각각의 출발 빌딩에서 모두가 닿는 빈 땅 0에 대한 탐색이 가능하며, 그 중 누적한 최솟값을 최종 답으로 리턴할 수 있다.
package to_0818_A;
import java.util.*;
class Solution {
public int solution(int[][] board){
int answer = 0;
int[] dx = {-1, 0, 1, 0};
int[] dy = {0, 1, 0, -1};
int n = board.length;
int[][] dist = new int[n][n];
Queue<int[]> Q = new LinkedList<>();
int emptyLand = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(board[i][j] == 1){
answer = Integer.MAX_VALUE;
Q.offer(new int[]{i, j});
int L = 0;
while(!Q.isEmpty()){
L++;
int len = Q.size();
for(int r = 0; r < len; r++){
int[] cur = Q.poll();
for(int k = 0; k < 4; k++){
int nx = cur[0] + dx[k];
int ny = cur[1] + dy[k];
if(nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == emptyLand){
board[nx][ny]--;
dist[nx][ny] += L;
Q.offer(new int[]{nx, ny});
answer = Math.min(answer, dist[nx][ny]);
}
}
}
}
emptyLand--;
}
}
}
return answer == Integer.MAX_VALUE ? -1 : answer;
}
public static void main(String[] args){
Solution T = new Solution();
System.out.println(T.solution(new int[][]{{1, 0, 2, 0, 1}, {0, 0, 0, 0, 0}, {0, 2, 1, 0, 0}, {2, 0, 0, 2, 2}, {0, 0, 0, 0, 0}}));
System.out.println(T.solution(new int[][]{{1, 0, 0, 1}, {0, 0, 2, 0}, {0, 0, 1, 0}, {2, 2, 0, 0}}));
System.out.println(T.solution(new int[][]{{1, 2, 0, 0}, {0, 0, 1, 2}, {0, 2, 0, 0}, {0, 2, 1, 0}}));
System.out.println(T.solution(new int[][]{{1, 0, 0, 1}, {0, 0, 2, 0}, {0, 0, 1, 0}, {2, 2, 0, 1}}));
}
}
- 다시 풀이 RE
package to_0818_B;
//집을 짓자 - RE 다시 풀기
import java.util.*;
class Solution {
public int solution(int[][] board){
int N = board.length;
int[][]dist = new int[N][N];
//4방향
int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
int emptyLand = 0;//최초
//1) 1인 빌딩 출발점으로 삼기 위해 큐에 담기
Queue<int[]> Q = new LinkedList<>();
for(int i=0; i<N; i++) {
for(int j =0; j<N; j++) {
if(board[i][j]==1) {
Q.offer(new int[] {i, j});
int lv = 0;
while(!Q.isEmpty()) {
lv++; //거리 처리
int len = Q.size();
for(int r =0; r<len ; r++) {
int[] cur = Q.poll();
for(int k=0; k<4; k++) {
int nx = cur[0] + dx[k];
int ny = cur[1] + dy[k];
if(nx <0 || ny<0 || nx >=N || ny>=N) continue;
if(board[nx][ny]==emptyLand) {
//닿은 부분은 중복으로 다음에도 닿아야 하기 때문에
board[nx][ny]--;//처리하고
Q.add(new int[] {nx, ny});
dist[nx][ny] += lv;
}
}
}
}
emptyLand--;//각 빌딩 1에 대하여 모두 순회하고 중복순회해야하기 때문에 그 기준값도 처리
}
}
}
int answer = Integer.MAX_VALUE;
//정답 처리
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
if(board[i][j] == emptyLand) {
answer = Math.min(answer, dist[i][j]);//거기에 누적된 거리합
}
}
}
return answer == Integer.MAX_VALUE ? -1 : answer;
}
public static void main(String[] args){
Solution T = new Solution();
System.out.println(T.solution(new int[][]{{1, 0, 2, 0, 1}, {0, 0, 0, 0, 0}, {0, 2, 1, 0, 0}, {2, 0, 0, 2, 2}, {0, 0, 0, 0, 0}}));
System.out.println(T.solution(new int[][]{{1, 0, 0, 1}, {0, 0, 2, 0}, {0, 0, 1, 0}, {2, 2, 0, 0}}));
System.out.println(T.solution(new int[][]{{1, 2, 0, 0}, {0, 0, 1, 2}, {0, 2, 0, 0}, {0, 2, 1, 0}}));
System.out.println(T.solution(new int[][]{{1, 0, 0, 1}, {0, 0, 2, 0}, {0, 0, 1, 0}, {2, 2, 0, 1}}));
}
}
🟩 6번. 숲속의 기사
풀이
- 결국 2에서 출발해서 4인 산딸기를 거쳐 3인 기사에게 가야하는 최단 시간 구해야 하는 문제이다.
- 처음에 2→4 , 4→ 3으로 BFS 할 생각을 했다
- 그런데 애초에 2와 3 각각에서 못가는 1만 제외하고 탐색하면서 BFS하고 그 값을 서로 +=lv 처리 하면 됐을 문제였다.
- 다시 말해, 2가 출발하여 1 제외한 모든 곳에 닿는 최소거리값에다가,
- 3이 출발하여 1 제외한 모든 곳에 닿는 최소 거리값을 누적하여 더하면 2와 3을 모두 거치는 셈이 되고
- 그 상태에서 애당초 값이 4였던 위치의 dist값들 중 최솟값을 고르면 2, 3, 4를 모두 거치는 최단거리를 찾게 된다.
package to_0818_8;
//숲속의 기사 문제 풀이 - BFS
import java.util.*;
class Solution {
static int[][] dist;
static int N, M;
static int[] dx = {0, 0, 1, -1};
static int[] dy = {1, -1, 0, 0};
//solution
public int solution(int[][] board){
int answer = Integer.MAX_VALUE;
N = board.length;
M = board[0].length;
dist = new int[N][M];
//2, 3 각각 출발해서 탐색한 거리를 서로 합친 4를 발견하면 그 중 최소값
Queue<int[]> Q = new LinkedList<>();
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
//출발은 2, 3 각각에서 1 제외한 모든 지점을 탐색하는 식으로
if(board[i][j] == 2 || board[i][j] == 3) {
Q.offer(new int[] {i, j});
int[][] ch = new int[N][M];//체크용 배열
ch[i][j] = 1;
int lv = 0;
while(!Q.isEmpty()){
lv++;
int len = Q.size();
for(int r = 0; r<len; r++) {
int[] cur = Q.poll();
for(int k =0; k<4; k++) {
int nx = cur[0] + dx[k];
int ny = cur[1] + dy[k];
if(nx <0 || ny< 0 || nx >=N || ny>=M )continue;
if(ch[nx][ny] == 0 && board[nx][ny] != 1) {
Q.offer(new int[] {nx, ny});
ch[nx][ny] = 1;
dist[nx][ny] += lv;//각각 접근하는 모든 레벨에 대하여 누적 처리
}
}
}
}
}
}
}
//정답 처리
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(board[i][j] == 4 && dist[i][j] > 0) {
answer = Math.min(answer, dist[i][j]);
}
}
}
return answer;
}
//실행 메인
public static void main(String[] args){
Solution T = new Solution();
System.out.println(T.solution(new int[][]{{4, 1, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 1, 0, 1, 0, 0},
{0, 2, 1, 1, 3, 0, 4, 0},
{0, 0, 0, 4, 1, 1, 1, 0}}));
System.out.println(T.solution(new int[][]{{3, 0, 0, 0, 1, 4, 4, 4},
{0, 1, 1, 0, 0, 0, 1, 0},
{0, 1, 4, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 1, 1, 0},
{4, 0, 0, 0, 1, 0, 0, 0},
{4, 1, 0, 0, 1, 0, 0, 0},
{4, 0, 0, 0, 0, 0, 1, 2}}));
System.out.println(T.solution(new int[][]{{4, 1, 0, 1, 0},
{0, 1, 0, 1, 0},
{0, 0, 2, 3, 4},
{0, 1, 0, 1, 0}}));
}
}
728x90
'알고리즘 이론 [개념] > [개념] 코테 알고리즘 공부 - 시즌 2' 카테고리의 다른 글
코테 | 그래프 섹션 - 다익스트라, 위상정렬 문풀 (0) | 2023.08.22 |
---|---|
코테 | 그래프 섹션 - 다익스트라 문풀 (0) | 2023.08.21 |
코테 | 강의 - 너비 우선 탐색 - BFS 섹션 - (1) (0) | 2023.08.16 |
코테 | 강의 - 깊이 우선 탐색 - DFS 섹션 - (2) (0) | 2023.08.14 |
코테 | 강의 - 깊이 우선 탐색 - DFS 섹션 - (1) (0) | 2023.08.09 |