[BOJ] 19236. 청소년 상어
2020. 7. 15. 03:29ㆍ알고리즘/백준 문제 풀이
https://www.acmicpc.net/problem/19236
접근 방법
후.. 너무 힘들었다 3시간은 걸린거 같다.
DFS로 구현을 했었다.
- 무조건 시작은 0,0 으로 시작을 한다.
- 상어가 0,0을 먹고 시작하니 0,0의 방향을 가지고 먹을 것이 있나 탐색을 한다.
- 먹을 것이 있으면 이제 재귀로 쭉 들어가본다.
- 가야할 방향에 먹을 것이 더 이상 없다면 끝을 내고 결과값을 저장한다.(최대로)
주의 사항
- 같은 맵을 쓰면 안된다. 재귀호출을 한번 다 돌리면 다시 돌려놔줘야한다.
- 먹을 것이 없다는 것은 같은 방향으로 쭉 갔을 때 더 이상 존재하지 않는 것이다.
Need Know
- DFS
- 재귀 호출의 이해?
- 깊은 복사와 얕은 복사의 차이
- 그냥 시뮬레이션..
전체 코드 ( Java )
import java.io.*;
import java.util.*;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int[] dx = {-1, -1, 0, 1, 1, 1, 0, -1};
static int[] dy = {0, -1, -1, -1, 0, 1, 1, 1};
static int[][] map = new int[4][4];
static Fish[] fish = new Fish[17];
static int ans =0;
public static void main(String[] args) throws IOException {
set();
solve();
bw.flush();
bw.close();
br.close();
}
static void set() throws IOException {
for(int i=0; i<4; i++){
StringTokenizer st = new StringTokenizer(br.readLine());
for(int k=0; k<4; k++){
int number = Integer.parseInt(st.nextToken());
int direction = Integer.parseInt(st.nextToken())-1;
map[i][k] = number;
fish[number] = new Fish(i,k,direction,1);
}
}
}
static void solve() throws IOException {
int first_eat = map[0][0];
map[0][0] = -1;
fish[first_eat].state = 0; // 물고기가 죽어버림
dfs(0,0,fish[first_eat].dir,first_eat);
bw.write(ans+"");
}
static void dfs(int shark_x, int shark_y, int shark_direction ,int eat) {
int[][] copyMap = new int[4][4];
Fish[] copyFish = new Fish[17];
for(int i=0;i<4; i++){
copyMap[i] = map[i].clone();
}
copyFish = fish.clone();
sort_map();
// for(int i=0; i<4; i++){
// for(int k=0; k<4; k++){
// System.out.print(map[i][k] +" ");
// }
// System.out.println();
// }
for(int i=1;i<4; i++){
int nx = shark_x + dx[shark_direction]*i;
int ny = shark_y + dy[shark_direction]*i;
if(nx<4 && ny<4 && nx>=0 && ny>=0) {
if(map[nx][ny] ==0) continue;
map[shark_x][shark_y] = 0;
int eatable = map[nx][ny];
// System.out.println(eatable);
map[nx][ny] = -1;
fish[eatable].state = 0;
dfs(nx,ny,fish[eatable].dir,eat+eatable);
map[nx][ny] = eatable;
fish[eatable].state = 1;
map[shark_x][shark_y] = -1;
}else {
break;
}
}
for(int i=0; i<4; i++) {
map[i] = copyMap[i].clone();
}
for(int i=1; i<=16; i++) {
fish[i] = copyFish[i];
}
ans = Math.max(eat,ans);
}
static void sort_map(){
for(int i=1; i<=16; i++){
if(fish[i].state==0) continue;
Fish now = fish[i];
int x = now.x, y = now.y, dir = now.dir;
for(int k=0; k<8; k++) {
int nd = (dir+k)%8;
int nx = x + dx[nd];
int ny = y + dy[nd];
if(nx>=4||ny>=4||nx<0||ny<0||map[nx][ny]==-1) continue;
int fish_num = map[nx][ny];
map[nx][ny] = map[x][y];
map[x][y] = fish_num;
fish[i] = new Fish(nx,ny,nd,1);
// 물고기가 존재 한다면
if(fish_num != 0){
fish[fish_num] = new Fish(x,y,fish[fish_num].dir,1);
}
break;
}
}
}
}
class Fish{
int x,y,dir,state;
public Fish(int x, int y, int dir,int state) {
this.x = x;
this.y = y;
this.dir = dir;
this.state = state;
}
}
'알고리즘 > 백준 문제 풀이' 카테고리의 다른 글
[BOJ] 5582. 공통 부분 문자열 (0) | 2020.07.18 |
---|---|
[BOJ] 14890. 경사로 (0) | 2020.07.15 |
[BOJ] 2342. Dance Dance Revolution (0) | 2020.07.14 |
[BOJ] 2718. 타일 채우기 (0) | 2020.07.13 |
[BOJ] 1915. 가장 큰 정사각형 (0) | 2020.07.12 |