250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 전화번호속의암호
- java
- 에라토스테네스의채
- 중복순열
- 정올 1620
- Bfs와DFS
- 코테
- N과M
- BFS
- 알고리즘개념
- 자바
- 순열
- 정보처리기사
- 백준
- 완전탐색
- 자바 코테
- 중복조합
- 백준2251
- 완탐
- 주사위굴리기2
- 파티션 크기 조정
- 삼성역테
- 재귀함수
- 코테준비
- D드라이브생성
- 백준15652
- 알고리즘
- 볼륨 만들기
- 백준13458
- 23288
Archives
- Today
- Total
뚱땅뚱땅
[문제] 백준 16236번 아기 상어 본문
728x90
내 풀이
여기서의 포인트는 bfs를 이용해서 최단거리를 구하는 것이다.
처음에 거리를 구할 때 원래 거리 구하던 방식이었던 dfs로 해보니 계속 엉뚱한 답이 나왔었다.
bfs, dfs를 이용해 최단거리 구하는 방법 꼭 익힐 것!!
public class BOJ_16236 {
static int N, sharkW = 2, sharkX, sharkY; // 상어 무게, 현재 상어 좌표
static int[][] map;
static int time = 0, dist, prey = 0; // 걸리는 시간, 거리, 먹은 물고기 수
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(in.readLine());
map = new int[N][N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(in.readLine(), " ");
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] == 9) { // 상어 위치
sharkX = i;
sharkY = j;
map[i][j] = 0;
}
}
}
// 상어가 물고기 먹을 수 있을 때 까지 반복
boolean flag = true;
while (flag) {
flag = canEat();
}
System.out.println(time);
}
static int[] dx = { -1, 1, 0, 0 };
static int[] dy = { 0, 0, -1, 1 };
// (sharkX, sharkY)-> (tx, ty) 로 이동하는 *최소 거리* 구하기
static void getDist(int tx, int ty, boolean[][] visited) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] { sharkX, sharkY, 1 }); // x,y좌표랑 depth 저장
visited[sharkX][sharkY] = true;
while (!q.isEmpty()) {
int[] curr = q.poll();
for (int d = 0; d < 4; d++) {
int nx = curr[0] + dx[d];
int ny = curr[1] + dy[d];
int nd = curr[2] + 1;
// 조건: 배열 내에 위치 && 아직 방문 x && 상어 무게 보다 같거나 작을 때 이동 가능
if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && map[nx][ny] <= sharkW) {
visited[nx][ny] = true;
q.offer(new int[] { nx, ny, nd });
}
}
// 먼저 도착한게 최단 거리
if (visited[tx][ty]) {
dist = curr[2];
break;
}
}
}
// 물고기 먹으러 가는 함수: 먹을 수 있으면 true, 없으면 false
static boolean canEat() {
int minD = Integer.MAX_VALUE; // 최소거리
int minX = N, minY = N; // 최소거리일 때의 좌표
boolean isFound = false; // 물고기 찾았는지
// 가장 가까운 한마리 정하기
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if ((i == sharkX && j == sharkY) || map[i][j] == 0) // 상어 위치이거나 물고기가 없으면 continue
continue;
if (map[i][j] < sharkW) { // 먹을 수 있는 후보: 상어무게보다 작을 때
dist = 0; // dist 0으로 초기화
getDist(i, j, new boolean[N][N]); // 거리 구하기
if (dist == 0) // 이동 못함-> continue
continue;
else { // 이동 가능
isFound = true; // 하나라도 찾으면 true
// 우선순위: 가장 가까이 있음 > 가장 위에 > 가장 왼쪽
if (dist < minD) {
minD = dist;
minX = i;
minY = j;
} else if (dist == minD) {
if (i < minX) {
minX = i;
minY = j;
} else if (i == minX) {
if (j < minY) {
minY = j;
}
}
}
}
}
}
}
// 위에서 물고기 찾으면,
if (isFound) {
time += minD; // 소요 시간 갱신: 최소 거리만큼 더해준다.
sharkX = minX; // 현재 상어 위치 갱신: 해당 물고기 위치로 이동
sharkY = minY;
map[sharkX][sharkY] = 0;// 먹었으니까 0
prey++; // 물고기 먹은 수 ++
// 상어 무게만큼 먹이 먹었으면 무게 하나 증가, 먹은 물고기 수 0으로 초기화
if (prey == sharkW) {
prey = 0;
sharkW++;
}
}
return isFound;
}
}
728x90
'알고리즘 > 백준' 카테고리의 다른 글
[문제] 백준 17471번 게리맨더링 (0) | 2021.04.10 |
---|---|
[문제] 백준 2636번 치즈 (0) | 2021.03.25 |
[문제] 백준 1182번 부분수열의 합 (0) | 2021.03.09 |
[문제] 백준 2580번 스도쿠 (0) | 2021.03.09 |
[문제] 백준 2661번 좋은수열 (0) | 2021.03.09 |
Comments