developer-ellen
인간 디버거의 로그 찍기
developer-ellen
전체 방문자
오늘
어제
  • 분류 전체보기 (217)
    • 회고록 (0)
    • 취뽀 및 커리어 여정의 Stack (2)
      • SSAFY 7기 (2)
    • 프로그래밍공부 (24)
      • c++ (0)
      • JAVA (3)
      • Spring (5)
      • design pattern (3)
      • BackDB (1)
      • Servlet&JSP (3)
      • Vue (4)
      • JPA (4)
      • Infra (1)
      • Linux (0)
    • AI (3)
      • papers (3)
      • trend (0)
    • 프로젝트진행 (0)
      • 데이터베이스 (0)
      • 서버개발 (0)
      • 인공지능 (0)
      • 하루정리 (0)
    • 포트폴리오 (0)
    • 알고리즘 (158)
      • 알고리즘문풀 (155)
      • 알고리즘공부 (3)
    • 통계공부 (15)
      • 시계열분석 (15)
      • 회귀분석 (0)
    • CS (14)
      • 컴퓨터네트워크 (4)
      • 운영체제 (8)
      • 데이터베이스 (2)
    • 주저리주저리 (0)
      • 필사 (0)
    • 취업관련정보 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 운영체제인터럽트
  • 삼성코테자바준비
  • 카카오코테java풀이
  • 통계학
  • BOJ파이썬풀이
  • 삼성코테준비
  • 시계열
  • 카카오코테
  • c++ 빌더 패턴
  • 삼성코테파이썬
  • 통계분석
  • 데이터분석
  • 삼성코테구현풀이
  • SW역량테스트파이썬풀이
  • 삼성코테파이썬준비
  • 백준파이썬풀이
  • MA모형
  • c++디자인패턴
  • 삼성코테기출자바풀이
  • SW역량테스트파이썬
  • 시계열분석
  • 삼성코테구현문제추천
  • 삼성코테자바풀이
  • 삼성코테파이썬풀이
  • Arima
  • 삼성코테기출
  • ARIMA모형
  • 코테파이썬
  • AR모형
  • 삼성코테자바꿀팁

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
developer-ellen

인간 디버거의 로그 찍기

알고리즘/알고리즘문풀

BOJ - 어른 상어 19237번 (JAVA)

2022. 4. 30. 13:30

❓ 문제 - 백준 어른 상어 19237번 - JAVA 풀이법

 

출처 

(https://www.acmicpc.net/problem/19237)

 

 

📝 문제해결법

1. 이 문제는 구현로 풀었다.

  • map이라는 2차원 배열에 상어의 번호를 저장한다.
  • Node[]라는 객체 배열로 각 상어에 인덱스에 맞는 상어의 정보(위치 x, y, 방향 dir)를 저장한다. 
  • Smell이라는 2차원 객체로 어떤 상어가 냄새를 남겼는지, 그리고 남긴 시점은 언제인지를 체크 저장한다.
  • shark_dir이라는 3차원 배열로 각 방향에 맞춰 방향의 우선순위를 저장한다.
  • check() 메소드를 통해 격자 안에 1번의 상어만 남았는지 체크한다. 
  • 상어의 움직임에서 처음에 각 상어의 이동이 시작되면 방향을 우선순위에 맞춰 정하고 해당 방향으로 이동했을 때 만약 상어가 존재하지 않는 곳이라면 해당 상어의 정보를 남김 처리하고, 이미 존재한 곳이라면 상어의 숫자를 비교해서 더 작은 숫자를 가진 상어만 남고 나머지는 격자밖으로 쫓겨남 처리를 한다.
  • 방향을 정할 때 첫 번째로 자기 방향에 맞는 우선순위를 토대로 냄새가 존재하지 않는 방향을 찾고, 만약 못 찾으면 자기 냄새가 있는 곳을 찾아서 해당 방향으로 선정한다.
  • 냄새에 대한 처리는 냄새를 k초 뒤에 제거 처리하는 게 아니라 smell이라는 위치에 상어의 번호와 해당 시점을 기록하고 냄새가 존재하는지 여부를 따질 때 해당 냄새에 기록된 시점+k가 현재 시점보다 작을 경우 냄새가 제거된 것으로 맞춰서 구현한다.

 

💻 소스코드

// BOJ - 어른 상어(19237번)
// 구현

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_19237 {
	public static int n, m, k;
	public static int[][] map;
	public static class Node {
		int x;
		int y;
		int dir;
		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}
		public Node(int x, int y, int dir) {
			this.x = x;
			this.y = y;
			this.dir = dir;
		}
	}
	
	public static class Smell {
		int num;
		int time;
		public Smell(int num, int time) {
			this.num = num;
			this.time = time;
		}
	}
	public static Node[] shark;
	public static int[] dx = {-1, 1, 0, 0};
	public static int[] dy = {0, 0, -1, 1};
	public static int[][][] shark_dir;
	public static Smell[][] smell;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		k = Integer.parseInt(st.nextToken());
		map = new int[n][n];
		smell = new Smell[n][n];
		shark = new Node[m+1];
		shark_dir = new int[m+1][4][4];
		
		for(int i=0;i<n;i++) {
			st = new StringTokenizer(br.readLine(), " ");
			for(int j=0;j<n;j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				if(map[i][j] != 0) {
					shark[map[i][j]] = new Node(i, j);
					smell[i][j] = new Smell(map[i][j], k);
				}
			}
		}
		
		st = new StringTokenizer(br.readLine(), " ");
		for(int i=1;i<=m;i++) {
			shark[i].dir = Integer.parseInt(st.nextToken())-1;
		}
		
		// 상어들의 방향 우선순위 받기
		for(int s=1;s<=m;s++) {
			for(int i=0;i<4;i++) {
				st = new StringTokenizer(br.readLine(), " ");
				for(int j=0;j<4;j++) {
					shark_dir[s][i][j] = Integer.parseInt(st.nextToken()) -1;
				}
			}
		}
	
		int time = 0;
		while(time <= 1000) {
			if(check()) {
				break;
			}
			time++;
			// 상어의 이동 시작
			for(int s=1;s<=m;s++) {
				
				if(shark[s] == null) continue;
				Node node = shark[s];
				int d = node.dir;
				boolean check = false;
				// 냄새 없는 방향 잡기
				for(int i=0;i<4;i++) {
					int dir = shark_dir[s][d][i];
					int nx = node.x + dx[dir];
					int ny = node.y + dy[dir];
					if(0 <= nx && nx < n && 0 <= ny && ny < n) {
						if((smell[nx][ny] == null) || (smell[nx][ny].time < time)) {
							// 이동
							d = dir;
							check = true;
							break;
						}
					}
				}
				// 방향 못 찾음 -> 자기 냄새 있는 곳 찾기
				if(!check) {
					for(int i=0;i<4;i++) {
						int dir = shark_dir[s][d][i];
						int nx = node.x + dx[dir];
						int ny = node.y + dy[dir];
						if(0 <= nx && nx < n && 0 <= ny && ny < n) {
							if(smell[nx][ny].num == s) {
								// 이동
								d = dir;
								break;
							}
						}
					}
				}
				
				
				int nx = node.x + dx[d];
				int ny = node.y + dy[d];
				node.dir = d;
			
				if(map[nx][ny] == 0) {
					map[nx][ny] = s;
					map[node.x][node.y] = 0;
					shark[s].x = nx;
					shark[s].y = ny;
				} else if(map[nx][ny] > s){
					int delete = map[nx][ny];
					shark[delete] = null;
					map[nx][ny] = s;
					map[node.x][node.y] = 0;
					shark[s].x = nx;
					shark[s].y = ny;
				} else {
					shark[s] = null;
					map[node.x][node.y] = 0;
				}
				
				
				
			
			}
			
			// 냄새 뿌리기
			for(int s=1;s<=m;s++) {
				if(shark[s] != null) {
					smell[shark[s].x][shark[s].y] = new Smell(s, k+time);
				}
			}
		}
		
		System.out.println(time>1000?-1:time);
	}
	public static void print() {
		for(int i=0;i<n;i++) {
			for(int j=0;j<n;j++) {
				System.out.print(map[i][j] +" ");
			}
			System.out.println();
		}
		System.out.println();
	}
	public static boolean check() {
		for(int i=2;i<=m;i++) {
			if(shark[i] != null) {
				return false;
			}
		}
		return true;
	}

}

'알고리즘 > 알고리즘문풀' 카테고리의 다른 글

BOJ - 컨베이어 벨트 위의 로봇 20055번 (JAVA)  (0) 2022.04.30
BOJ - 스타트택시 19238번 (JAVA)  (0) 2022.04.30
BOJ - 청소년 상어 19236번 (JAVA)  (0) 2022.04.30
BOJ - 모노미노도미노2 20061번 (JAVA)  (0) 2022.04.30
BOJ - 원판 돌리기 17822번 (JAVA)  (0) 2022.04.30
    '알고리즘/알고리즘문풀' 카테고리의 다른 글
    • BOJ - 컨베이어 벨트 위의 로봇 20055번 (JAVA)
    • BOJ - 스타트택시 19238번 (JAVA)
    • BOJ - 청소년 상어 19236번 (JAVA)
    • BOJ - 모노미노도미노2 20061번 (JAVA)
    developer-ellen
    developer-ellen

    티스토리툴바