19236번: 청소년 상어
첫째 줄부터 4개의 줄에 각 칸의 들어있는 물고기의 정보가 1번 행부터 순서대로 주어진다. 물고기의 정보는 두 정수 ai, bi로 이루어져 있고, ai는 물고기의 번호, bi는 방향을 의미한다. 방향 bi는
www.acmicpc.net
0. 백트래킹 / 구현 문제
1. 백트래킹을 위하여, 상어의 각 이동 단계마다 map과 물고기 방향 정보를 저장한다
2. 해당 상황에서 물고기 이동 - 가능한 모든 상어 이동에 대해 재귀를 돌린 다음, 저장해둔 정보를 복원하고 이전 단계로 돌아간다
3. 각 재귀 단계에서 먹은 물고기 번호의 합을 저장, 더이상 진행 불가능할때 전역변수인 maxEat과 비교, 갱신한다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main{
static int[][] dir = {
{-1,0},{-1,-1},{0,-1},{1,-1},
{1,0},{1,1},{0,1},{-1,1}
};
static int maxEat=0;
static boolean[] deadFish;
static int[][] fish;
static int[][] map;
public static void main(String[] args)throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
map = new int[4][4];
fish = new int[17][3];
deadFish = new boolean[17];
for (int i = 0; i < 4; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < 4; j++) {
int num = pint(st.nextToken());
int dir = pint(st.nextToken());
map[i][j]=num;
fish[num][0]=i;
fish[num][1]=j;
fish[num][2]=dir-1;
}
}
//fish[0] = shark
deadFish[map[0][0]]=true;
maxEat+=map[0][0];
fish[0][2] = fish[ map[0][0] ][2];
map[0][0]=-1;
rec(maxEat);
System.out.println(maxEat);
}
static void rec(int eat) {
//comparemaxEat
if(maxEat<eat)maxEat=eat;
int[][]tmpMap = new int[4][4];
int[][] tmpFish = new int[17][3];
boolean[] tmpDeadFish = new boolean[17];
//backup
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
tmpMap[i][j]=map[i][j];
}
}
for (int i = 0; i < 17; i++) {
tmpFish[i][0]=fish[i][0];
tmpFish[i][1]=fish[i][1];
tmpFish[i][2]=fish[i][2];
tmpDeadFish[i]=deadFish[i];
}
//fish move
for (int i = 1; i < 17; i++) {
if(deadFish[i])continue;//죽었다면 넘어감
int curX = fish[i][0], curY = fish[i][1], curDir = fish[i][2];
for (int j = 0; j < 8; j++) {
//ok?
int nX = curX+dir[curDir][0];
int nY = curY+dir[curDir][1];
if(nX<0 || nY<0 || nX>=4 || nY>=4 || map[nX][nY]==-1) {
curDir= (curDir+1)%8; continue;
}
//swap
int tmp = map[nX][nY];
map[nX][nY]=map[curX][curY];
map[curX][curY]=tmp;
fish[i][0]=nX;fish[i][1]=nY;
fish[i][2]=curDir;
if(tmp!=0) {
fish[tmp][0]=curX;
fish[tmp][1]=curY;
}
break;
}
}
//shark move
//eat
map[ fish[0][0] ][ fish[0][1] ]=0;//빈 공간화
while(true) {
fish[0][0]+=dir[fish[0][2]][0];
fish[0][1]+=dir[fish[0][2]][1];
if(fish[0][0]<0 || fish[0][0]>=4 || fish[0][1]<0 || fish[0][1]>=4) {
break;
}
if(map[fish[0][0]][fish[0][1]]==0)continue;
int tmp = map[ fish[0][0] ][ fish[0][1] ];
map[ fish[0][0] ][ fish[0][1] ]=-1;
deadFish[tmp]=true;
int tmpShakeDir = fish[0][2];
fish[0][2]=fish[tmp][2];
rec(eat+tmp);
fish[0][2]=tmpShakeDir;
map[ fish[0][0] ][ fish[0][1] ]=tmp;
deadFish[tmp]=false;
}
//return
//restore
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
map[i][j]=tmpMap[i][j];
}
}
for (int i = 0; i < 17; i++) {
fish[i][0]=tmpFish[i][0];
fish[i][1]=tmpFish[i][1];
fish[i][2]=tmpFish[i][2];
deadFish[i]=tmpDeadFish[i];
}
return;
}
static int pint(String s) {
return Integer.parseInt(s);
}
}
'알고리즘 문제 풀이 > BOJ 골드' 카테고리의 다른 글
[백준] 1959 - 달팽이3 (0) | 2021.11.04 |
---|---|
[백준] 16973 - 직사각형 탈출 (0) | 2021.11.04 |
[백준] 23288 - 주사위 굴리기 2 (0) | 2021.11.03 |
[백준] 20058 - 마법사 상어와 파이어스톰 (0) | 2021.10.25 |
[백준] 21610 - 마법사 상어와 비바라기 (0) | 2021.10.25 |
[백준] 1339 - 단어수학 (0) | 2021.10.10 |
[백준] 14938 - 서강그라운드 (0) | 2021.10.03 |