(JAVA) 2382. [모의 SW 역량테스트] 미생물 격리

Standard

문제 링크: https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV597vbqAH0DFAVl

크게 복잡하지는 않았던 문제.
– 맵 만들고 나서, 매 시간 1. 정해진 대로 이동 후 방향과 갯수 수정이 필요한 경우 수정 2. 같은 위치에 있는 군집들을 merge 하도록 구현
– 정해진 시간이 끝난 후, 각 군집의 갯수를 더하면 정답

import java.io.*;
import java.util.*;

public class Solution {
	
	public static void main(String[] args) throws IOException {
		// System.setIn(new FileInputStream("./src/sample_input.txt"));
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
		
		try {
			int numCases = Integer.parseInt(reader.readLine());
	
			for (int num = 0; num < numCases; num++) {
				writer.write("#" + String.valueOf(num + 1) + " ");
				
				String[] tmp = reader.readLine().split(" ");
				int numN = Integer.parseInt(tmp[0]); // 셀 갯수
				int numM = Integer.parseInt(tmp[1]); // 격리 시간
				int numK = Integer.parseInt(tmp[2]); // 미생물 갯수
				
				int[] arrayY = new int[numK];	// 세로 위치
				int[] arrayX = new int[numK];	// 가로 위치
				int[] arrayNum = new int[numK];	// 미생물 수
				int[] arrayMove = new int[numK];// 이동 방향 (1: 상, 2: 하, 3: 좌, 4: 우)
				
				// Map 생성
				for (int i = 0; i < numK; i++) {
					String[] tmp_ = reader.readLine().split(" ");
					
					arrayY[i] = Integer.parseInt(tmp_[0]);
					arrayX[i] = Integer.parseInt(tmp_[1]);
					arrayNum[i] = Integer.parseInt(tmp_[2]);
					arrayMove[i] = Integer.parseInt(tmp_[3]);
				}
				
				// 시간 단위 처리 
				for (int i = 0; i < numM; i++) {
					// 각 미생물 별로 처리 
					for (int j = 0; j < numK; j++) {
						if (arrayNum[j] == 0) // 전부 죽은 경우 혹은 합쳐져서 무효화된 경우 확인할 필요가 없음
							continue;
						
						switch (arrayMove[j]) { // 이동
						case 1: // 상 
							arrayY[j]--;
							break;
						case 2: // 하
							arrayY[j]++;
							break;
						case 3: // 좌 
							arrayX[j]--;
							break;
						case 4: // 우
							arrayX[j]++;
							break;
						}
						
						if (arrayY[j] == 0) { // 맨 위에 닿은 경우
							arrayNum[j] /= 2;
							arrayMove[j] = 2; // 상에서 하로 변경 
						}						
						else if (arrayY[j] == numN - 1) { // 맨 아래에 닿은 경우
							arrayNum[j] /= 2;
							arrayMove[j] = 1; // 하에서 상으로 변경 
						}
						else if (arrayX[j] == 0) { // 맨 왼쪽에 닿은 경우
							arrayNum[j] /= 2;
							arrayMove[j] = 4; // 좌에서 우로 변경 
						}						
						else if (arrayX[j] == numN - 1) { // 맨 오른쪽에 닿은 경우
							arrayNum[j] /= 2;
							arrayMove[j] = 3; // 우에서 좌로 변경 
						}
					}
					
					// 합칠 필요가 있는 경우 합침 
					for (int j = 0; j < numK; j++) {
						if (arrayNum[j] == 0) // 전부 죽은 경우 확인할 필요가 없음
							continue;
						
						int Y = arrayY[j];
						int X = arrayX[j];
						int max = j;
						int total = arrayNum[j];
						
						// 같은 위치에 있는 다른 군집들 탐색
						List<Integer> sameLocation = new ArrayList<Integer>();
						
						// 자기 이전의 군집들은 탐색할 필요가 없음 (아직 같은 위치를 찾아본 적이 없는 경우만 여기 도달)
						for (int k = j + 1; k < numK; k++) {
							if (arrayNum[k] != 0 && arrayY[k] == Y && arrayX[k] == X) {
								sameLocation.add(k);
								total += arrayNum[k];
								if (arrayNum[max] < arrayNum[k])
									max = k;
							}
						}
						
						if (sameLocation.size() != 0) {
							// 갯수가 제일 많은 군집의 방향 이용
							arrayMove[j] = arrayMove[max];
							// 총 갯수 넣음
							arrayNum[j] = total;
							
							// j 외의 군집 내용은 모두 무효화
							for (int idx: sameLocation) {
								arrayY[idx] = -1; // 무효화 
								arrayX[idx] = -1; // 무효화
								arrayNum[idx] = 0;
							}
						}
					}
				}
				
				// 정답 구하기
				int answer = 0;
				for (int i = 0; i < numK; i++)
					answer += arrayNum[i];
				
				writer.write(answer + System.lineSeparator());
				writer.flush();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.