본문 바로가기

[IT] 코딩테스트/[문제 및 풀이] 백준

[백준] 17143 낚시왕 / 자바(Java)

728x90

문제

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

 

17143번: 낚시왕

낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다.

www.acmicpc.net

 


해설

상어 객체를 만들어 낚시왕이 상어를 잡는 부분에는 상어배열을, 상어가 이동하는 부분에는 상어 큐를 사용해서 해결하였습니다.

 

상어의 이동 부분에 상어 큐를 사용한 이유는 상어의 이동들은 모두 동시에 이동하기 때문에 큐로 상어 객체이 이동된 이후의 값을 추가하며 넣고 배열에 다시 넣으며 상어끼리 먹는 구간을 구현했습니다.

 


코드

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

public class Main{
	
	static class shark{
		int r, c, speed, dir, size;
		public shark(int r, int c, int speed, int dir, int size) {
			super();
			this.r = r;
			this.c = c;
			this.speed = speed;
			this.dir = dir;
			this.size = size;
		}
		
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int R = Integer.parseInt(st.nextToken());
		int C = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		shark[][] map=new shark[R][C];
		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()); 
			map[r-1][c-1]=new shark(r-1, c-1, s, d-1, z);
		}
		
		// 구현 시작
		int sum=0;// 총 상어 크기
		// 낚시왕의 위치별로 표현(낚시왕이동)
		for(int i=0;i<C;i++) {
//			System.out.println("Col"+i);
			// 1) 낚시왕의 아래에 있는 상어 잡기
			// 각 상어별 낚시왕과 동일 C이고 죽지않은 가장 가까운 r인경우 잡힘
			for(int j=0;j<R;j++) {
				if(map[j][i]!=null) {
					sum += map[j][i].size;
					map[j][i]=null;
					break;
				}
			}
			// 상하, 우좌
			int dr[] = {-1,1,0,0};
			int dc[] = {0,0,1,-1};
			// 상어 이동
			Queue<shark> q = new LinkedList<>();
			// 맵의 상어를 큐로이동
			for(int j=0;j<R;j++) {
				for(int k=0;k<C;k++) {
					if(map[j][k]!=null)q.offer(new shark(j, k, map[j][k].speed, map[j][k].dir, map[j][k].size));
				}
			}

			map=new shark[R][C];
			
			while(!q.isEmpty()) {
				shark cur = q.poll();
//				System.out.println(cur.r+" "+cur.c);
				// 반복되는 구간을 줄여 이동범위 감소
				int speed = cur.speed;
				if(cur.dir<2) {
					speed%=(R-1)*2;
				}else {
					speed%=(C-1)*2;
					
				}
				
				for(int times=0;times<speed;times++) {
					int newr = cur.r+dr[cur.dir];
					int newc = cur.c+dc[cur.dir];
					
					if(newr<0||newc<0||newr>=R||newc>=C) {
						cur.r-=dr[cur.dir];
						cur.c-=dc[cur.dir];
						if(cur.dir%2==0) {
							cur.dir++;
						}else {
							cur.dir--;
						}
						continue;
					}
					cur.r=newr;
					cur.c=newc;
				}
				// 지도에 다시 그리며 상어끼리 먹거나 먹힘
				if(map[cur.r][cur.c]!=null) {
					if(map[cur.r][cur.c].size<cur.size) {
						map[cur.r][cur.c]=new shark(cur.r, cur.c, cur.speed, cur.dir, cur.size);
					}
				}else {
					map[cur.r][cur.c]=new shark(cur.r, cur.c, cur.speed, cur.dir, cur.size);
				}
			}

		}
		System.out.println(sum);
	}
}
728x90