본문 바로가기

코딩테스트/JAVA

[백준 JAVA] 17143번: 낚시왕

https://www.acmicpc.net/problem/17143

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class Main {
	public static int R, C, M, ans = 0;
	public static List<shark> sharks = new ArrayList<>();
	public static shark[][] map;
	public static int[] dr = {0, -1, 1 ,0, 0};
	public static int[] dc = {0, 0, 0, 1, -1};

	public static class shark {
		int r, c, s, d, z;

		public shark(int r, int c, int s, int d, int z) {
			super();
			this.r = r;
			this.c = c;
			this.s = s;
			this.d = d;
			this.z = z;
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		// 1. 입력받기
		R = Integer.parseInt(st.nextToken());
		C = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		map = new shark[R + 1][C + 1];
		
		// 1-1. 상어 리스트 입력받기
		for (int i = 0; i < M; i++) {
			st = new StringTokenizer(br.readLine());
			int r = Integer.parseInt(st.nextToken());
			int c = Integer.parseInt(st.nextToken());
			int s = Integer.parseInt(st.nextToken());
			int d = Integer.parseInt(st.nextToken());
			int z = Integer.parseInt(st.nextToken());
			if(d == 1 || d == 2) {// 방향이 세로인 경우
				s = s % ((2 * R) - 2);
			} else { // 방향이 가로인 경우
				s = s % ((2 * C) - 2);
			}
			shark cur = new shark(r, c, s, d, z);
			sharks.add(cur);
			map[r][c] = cur;
		}

		// 2. 한칸씩 이동하며 상어 포획
		for (int i = 1; i <= C; i++) { // 가로로 한칸씩 이동하며
			for (int j = 1; j <= R; j++) { // 가장 가까운 칸부터
				if (map[j][i] != null) { // 상어가 있는 지 검사
					shark tmp = map[j][i];
					ans += map[j][i].z;
					sharks.remove(tmp);
					break;
				}
			}
			move(); // 3. 상어 이동
		}

		// 4. 정답 출력
		System.out.println(ans);
	}

	private static void move() {
		// 3-1. map 비우기
		for (int i = 1; i <= R; i++) {
			Arrays.fill(map[i], null);
		}
		
		// 3-2. 상어 이동하기
		for (int i = sharks.size() - 1; i >= 0; i--) {
			shark cur = sharks.get(i);
			int cnt = cur.s;
			
			while(cnt > 0) {
				int nr = cur.r + dr[cur.d];
				int nc = cur.c + dc[cur.d];
				if(nr <= 0 || nr > R || nc <= 0 || nc > C) {
					if(cur.d % 2 == 1) {
						cur.d += 1;
					} else {
						cur.d -= 1;
					}
					nr = cur.r + dr[cur.d];
					nc = cur.c + dc[cur.d];
				}
				cur.r = nr;
				cur.c = nc;
				cnt--;
			}
			
			// 3-3. map에 채우기
			if (map[cur.r][cur.c] != null) { // 같은 공간에 상어가  있다면
				if(map[cur.r][cur.c].z < cur.z) { // 원래 있던 상어가 작다면
					shark tmp = map[cur.r][cur.c];
					// 지금 상어 넣어주기
					map[cur.r][cur.c] = cur;
					sharks.remove(tmp);
				} else { // 원래 있던 상어가 크다면
					sharks.remove(cur);
				}
			} else { // 같은 공간에 상어가 없다면
				map[cur.r][cur.c] = cur;
			}
		}
	}
}

 

리스트에서 삭제할땐 반드시 뒤에서부터 삭제해

 

풀이 사항

풀이 일자: 2024.10.10
풀이 시간: 3시간
채점 결과: 정답
예상 문제 유형: 구현
시간: 532 ms

풀이방법

  1. 상어 클래스를 생성하고 이 상어들을 관리할 ArrayList와 map을 만든다.
  2. map에 해당위치에 상어를 배치시키고 List에도 상어를 넣어준다. 주의할점은 map에서 상어를 잡았을때 리스트에서 상어를 제거해주기위해 같은 레퍼런스를 참조하는 객체를 넣어줘야한다는점이다.
  3. 가로로 한칸씩 이동하며 상어를 잡아준뒤 List에서 하나씩 뽑아서 상어를 이동시킨다. 이때 같은 구역에 있는 상어가 있는 경우 크기에 따라 삭제되므로 List에서 뒤부터 뽑아준다.