[백준 18405] 경쟁적 전염 (자바)
알고리즘/백준

[백준 18405] 경쟁적 전염 (자바)

반응형

백준 18405번 경쟁적 전염 (자바)

 

 

 

출처

www.acmicpc.net/problem/18405

 

18405번: 경쟁적 전염

첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치��

www.acmicpc.net

 

 

 

문제

NxN 크기의 시험관이 있다. 시험관은 1x1 크기의 칸으로 나누어지며, 특정한 위치에는 바이러스가 존재할 수 있다. 모든 바이러스는 1번부터 K번까지의 바이러스 종류 중 하나에 속한다.

시험관에 존재하는 모든 바이러스는 1초마다 상, 하, 좌, 우의 방향으로 증식해 나간다. 단, 매 초마다 번호가 낮은 종류의 바이러스부터 먼저 증식한다. 또한 증식 과정에서 특정한 칸에 이미 어떠한 바이러스가 존재한다면, 그 곳에는 다른 바이러스가 들어갈 수 없다.

시험관의 크기와 바이러스의 위치 정보가 주어졌을 때, S초가 지난 후에 (X,Y)에 존재하는 바이러스의 종류를 출력하는 프로그램을 작성하시오. 만약 S초가 지난 후에 해당 위치에 바이러스가 존재하지 않는다면, 0을 출력한다. 이 때 X와 Y는 각각 행과 열의 위치를 의미하며, 시험관의 가장 왼쪽 위에 해당하는 곳은 (1,1)에 해당한다.

예를 들어 다음과 같이 3x3 크기의 시험관이 있다고 하자. 서로 다른 1번, 2번, 3번 바이러스가 각각 (1,1), (1,3), (3,1)에 위치해 있다. 이 때 2초가 지난 뒤에 (3,2)에 존재하는 바이러스의 종류를 계산해보자.

1초가 지난 후에 시험관의 상태는 다음과 같다.

2초가 지난 후에 시험관의 상태는 다음과 같다.

결과적으로 2초가 지난 뒤에 (3,2)에 존재하는 바이러스의 종류는 3번 바이러스다. 따라서 3을 출력하면 정답이다.

 

 

 

입력

첫째 줄에 자연수 N, K가 공백을 기준으로 구분되어 주어진다. (1 ≤ N ≤ 200, 1 ≤ K ≤ 1,000) 둘째 줄부터 N개의 줄에 걸쳐서 시험관의 정보가 주어진다. 각 행은 N개의 원소로 구성되며, 해당 위치에 존재하는 바이러스의 번호가 공백을 기준으로 구분되어 주어진다. 단, 해당 위치에 바이러스가 존재하지 않는 경우 0이 주어진다. 또한 모든 바이러스의 번호는 K이하의 자연수로만 주어진다. N+2번째 줄에는 S, X, Y가 공백을 기준으로 구분되어 주어진다. (0 ≤ S ≤ 10,000, 1 ≤ X, Y ≤ N)

 

 

 

출력

S초 뒤에 (X,Y)에 존재하는 바이러스의 종류를 출력한다. 만약 S초 뒤에 해당 위치에 바이러스가 존재하지 않는다면, 0을 출력한다.

 

 

 

입출력 예

입출력 예 1
입출력 예 2

 

 

 

접근 방법

순서가 낮은 순서대로 전염을 진행해야 하기 때문에 처음에 값을 넣고 정렬을 시켜주어야 한다.

나는 class를 만들어 객체로 넣었기 때문에 기존 sort로는 불가능하다.

때문에 Comparator를 상속받아 compareTo를 사용해  큰 수가 들어오면 정렬시켜 주었다.

 

1. list에 바이러스 크기, 시간, x, y를 넣기 위해 클래스를 활용한다.

 

2. 위 정보를 정렬 후 큐에 넣기 bfs를 실행한다.

 

3. bfs에서 해당 배열의 원소가 0이어야 연산을 수행하며, 배열에는 바이러스를 넣고 시간은 +1 하여 넣어준다.

 

4. 큐에서 꺼낸 시간초가 s와 같은 경우 연산을 종료한다.

 

 

 

내 코드

package dfsbfs;

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

public class CompetitiveSpread3 {
	/**
	 * 백준 18405 경쟁적전염 (https://www.acmicpc.net/problem/18405)
	 */
	private static int n,k;
	private static int[][] map;
	
	private static int[] dx = {-1, 0, 1, 0};
	private static int[] dy = {0, 1, 0, -1};
	
	private static int s,x,y;
	
	private static ArrayList<Spread> virusList = new ArrayList<>();
	private static Queue<Spread> virus = new LinkedList<>();
	
	public static void main(String[] args) throws IOException {
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(reader.readLine());
		
		n = Integer.parseInt(st.nextToken());
		k = Integer.parseInt(st.nextToken());
		
		map = new int[n+1][n+1];
		
		for (int i=1; i<=n; i++) {
			st = new StringTokenizer(reader.readLine());
			for (int j=1; j<=n; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
				
				if (map[i][j] != 0) {
					virusList.add(new Spread(map[i][j], 0, i, j));
				}
			}
		}
		
		Collections.sort(virusList);
		for (int i=0; i<virusList.size(); i++) {
			virus.offer(virusList.get(i));
		}
		
		st = new StringTokenizer(reader.readLine());
		s = Integer.parseInt(st.nextToken());
		x = Integer.parseInt(st.nextToken());
		y = Integer.parseInt(st.nextToken());
		
		bfs();
		
		System.out.println(map[x][y]);
	}
	
	private static void bfs() {
		
		while (!virus.isEmpty()) {
			
			Spread spread = virus.remove();
			int qn = spread.num;
			int qs = spread.second;
			int qx = spread.x;
			int qy = spread.y;
			
			if (qs == s) break;
			
			for (int i=0; i<dx.length; i++) {
				int nx = qx + dx[i];
				int ny = qy + dy[i];
				
				if (nx < 1 || ny < 1 || nx > n || ny > n || map[nx][ny] != 0) {
					continue;
				}
				
				if (map[nx][ny] == 0) {
					map[nx][ny] = qn;
					virus.add(new Spread(qn, qs+1, nx, ny));
				}
			}
			
		}
		
	}

	static class Spread implements Comparable<Spread>{
		int x, y, second, num;
		public Spread(int num, int second, int x, int y) {
			this.num = num;
			this.second = second;
			this.x = x;
			this.y = y;
		}
		
		//중요! 
		//이것이 있어야 객체 정렬 가능
		@Override
		public int compareTo(Spread other) {
			if (this.num < other.num) {
				return -1;
			}
			return 1;
		}
	}
}

 

 

 

고려할 점

1. 순서를 고려하기 위해 정렬할 것

2. 객체를 정렬하기 위해 Comparator를 사용할 것

3. 시간과 바이러스 크기를 고려할 것

 

 

 

참고

github.com/ndb796/python-for-coding-test

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

[백준 6603] 로또 (자바)  (0) 2020.10.18
[백준 14501] 퇴사 (자바)  (0) 2020.10.18
[백준 2231] 분해합 (자바)  (0) 2020.10.15
[백준 2798] 블랙잭 (자바)  (0) 2020.10.15
[백준 2667] 단지번호붙이기 (자바)  (0) 2020.10.14