스터디/Algorithm
[백준] 말이 되고픈 원숭이 1600 java - bfs
혜유우
2024. 6. 20. 02:45
https://www.acmicpc.net/problem/1600
처음에 말의 이동이 잘 이해가 가지 않아서 어려웠고
두 번째 난관은 같은 위치에 있을 때에도
k를 쓴 갯수에 따라서 다른 경우로 봐야하는데, 이를 간과해서 어려웠다 !
틀린 코드
import java.io._;
import java.util._;
public class Main {
static int K, W, H;
static int\[\]\[\] graph;
static boolean\[\]\[\] visited;
static int\[\] dx1 = {0,0,1,-1};
static int\[\] dy1 = {1,-1,0,0};
static int\[\] dx2 = {2,2,1,1,-2,-2,-1,-1};
static int\[\] dy2 = {1,-1,2,-2,1,-1,2,-2};
static int bfs(int x, int y){
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{x,y,0,0});
visited[x][y] = true;
while(!q.isEmpty()){
int[] now = q.poll();
int nowX = now[0];
int nowY = now[1];
int cnt = now[2];
int kCnt = now[3];
if(nowX==H-1 && nowY==W-1){
return cnt;
}
if(kCnt<K){
for(int i=0;i<8;i++){
int nextX = nowX+dx2[i];
int nextY = nowY+dy2[i];
if(nextX>=0&&nextX<H && nextY>=0&&nextY<W){
if(!visited[nextX][nextY] && graph[nextX][nextY]==0){
q.add(new int[]{nextX, nextY, cnt+1, kCnt+1});
visited[nextX][nextY] = true;
}
}
}
} else {
for(int i=0;i<4;i++){
int nextX = nowX+dx1[i];
int nextY = nowY+dy1[i];
if(nextX>=0&&nextX<H && nextY>=0&&nextY<W){
if(!visited[nextX][nextY] && graph[nextX][nextY]==0){
q.add(new int[]{nextX, nextY, cnt+1, kCnt});
visited[nextX][nextY] = true;
}
}
}
}
}
return -1;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
K = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
W = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
graph = new int[H][W];
visited = new boolean[H][W];
for(int i=0;i<H;i++){
st = new StringTokenizer(br.readLine());
for(int j=0;j<W;j++){
graph[i][j] = Integer.parseInt(st.nextToken());
}
}
System.out.println(bfs(0,0));
}
반례
1
5 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 1
0 0 0 1 0
-> 6이 답인데 위의 코드로 하면 -1이 출력..
같은 위치에 있는 경우도 말로 이동한 것인지 아닌지에 따라서
다르게 봐야 함 !!!
정답 코드
import java.io.*;
import java.util.*;
public class Main {
static int K, W, H;
static int[][] graph;
static boolean[][][] visited;
static int[] dx1 = {0,0,1,-1};
static int[] dy1 = {1,-1,0,0};
static int[] dx2 = {2,2,1,1,-2,-2,-1,-1};
static int[] dy2 = {1,-1,2,-2,1,-1,2,-2};
static int bfs(int x, int y){
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{x,y,0,0});
visited[x][y][0] = true;
while(!q.isEmpty()){
int[] now = q.poll();
int nowX = now[0];
int nowY = now[1];
int cnt = now[2];
int kCnt = now[3];
if(nowX==H-1 && nowY==W-1){
return cnt;
}
for(int i=0;i<4;i++){
int nextX = nowX+dx1[i];
int nextY = nowY+dy1[i];
if(nextX>=0&&nextX<H && nextY>=0&&nextY<W){
if(!visited[nextX][nextY][kCnt] && graph[nextX][nextY]==0){
q.add(new int[]{nextX, nextY, cnt+1, kCnt});
visited[nextX][nextY][kCnt] = true;
}
}
}
if(kCnt<K){
for(int i=0;i<8;i++){
int nextX = nowX+dx2[i];
int nextY = nowY+dy2[i];
if(nextX>=0&&nextX<H && nextY>=0&&nextY<W){
if(!visited[nextX][nextY][kCnt+1] && graph[nextX][nextY]==0){
q.add(new int[]{nextX, nextY, cnt+1, kCnt+1});
visited[nextX][nextY][kCnt+1] = true;
}
}
}
}
}
return -1;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
K = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
W = Integer.parseInt(st.nextToken());
H = Integer.parseInt(st.nextToken());
graph = new int[H][W];
visited = new boolean[H][W][K+1];
for(int i=0;i<H;i++){
st = new StringTokenizer(br.readLine());
for(int j=0;j<W;j++){
graph[i][j] = Integer.parseInt(st.nextToken());
}
}
System.out.println(bfs(0,0));
}
}