카테고리 없음

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

배발자 2022. 10. 12.
반응형
package swea;

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

public class Solution_2382 {

	static int N,M,K;//크기, 격리시간, 군집의 개수 
	static int [][] map;  //뭉쳤을 때 군집 숫자 합산 
	static int [][] microbeNumber; // 뭉쳤을 때 가장 큰 군집 번호 저장.  
	static int [] dx = {0,0,0,-1,1}; 
	static int [] dy = {0,-1,1,0,0}; 
	static ArrayList <Microbe> microbeList; 
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); 
		StringTokenizer st = null; 
		StringBuilder sb = new StringBuilder(); 
		int testCase = Integer.parseInt(br.readLine()); 
		
		for(int t = 1; t<=testCase; t++) {
			
			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]; // 미생물 누적 개수 
			microbeNumber = new int [N][N]; // 최대 개수를 가진 미생물 번호 기록
			microbeList = new ArrayList<>(); // 미생물 리스트 
			
			for(int i=0; i<K; i++) { // 미생물 정보 리스트 담기 
				
				st = new StringTokenizer(br.readLine()); 
				int r = Integer.parseInt(st.nextToken()); 
				int c = Integer.parseInt(st.nextToken()); 
				int n = Integer.parseInt(st.nextToken()); 
				int d = Integer.parseInt(st.nextToken());
				
				microbeList.add(new Microbe(r, c, n, d, false)); 
			}
			
			
			while(M-->0) moveMicrobe();
			// 미생물 M번 움직여 	
			
			int sum = 0; 
			// 미생물 전체 누적 개수 합산 
			
			for(int i=0; i<microbeList.size(); i++) {
				if(microbeList.get(i).isEaten==false) {// 미생물 중 먹히지 않은 것들만 
					sum+=microbeList.get(i).n;  
				}
			}
	
			sb.append("#").append(t).append(" ").append(sum).append("\n"); 
		}
		
		bw.write(sb.toString());
		bw.flush();
		bw.close();
		br.close();
		
	}
	
	static boolean lineCheck(int line) {
	
		if(line == 0 || line == N-1)return true; 
		// 약품이 칠해진 구역일 때 
		return false; 
		// 약품이 칠해져있지 않은 구역일 때 
	}
	
	
	static void moveMicrobe() {
		
		map = new int [N][N]; 
		microbeNumber = new int [N][N]; 
	
		for(int i=0; i<N; i++) {
			Arrays.fill(map[i], 0); // map 에다가 미생물 개수 합산 누적하기 
			Arrays.fill(microbeNumber[i], -1); // 미생물 번호 0부터 K-1 까지니까 -1 로 초기값 세팅
		}
				
		for(int i=0; i<microbeList.size(); i++) {
			Microbe m = microbeList.get(i); 
			if(m.isEaten==true)continue; // 먹힌거는 무시 
			
			
			// 아래 코드는 상, 하, 좌, 우로 이동하는 코드이며 
			// lineCheck 메소드를 통해 약품이 칠해진 라인일 경우 true를 반환하며 
			// 해당 조건문에서 미생물의 수를 절반으로 만들어주고 방향을 바꾼다. 
			if(m.d == 1) { //상
				m.r --; 
				if(lineCheck(m.r)) {
					m.n /=2; 
					m.d = 2;
				}
			}
			else if (m.d == 2) { //하
				m.r ++;  
				if(lineCheck(m.r)) {
					m.n /=2; 
					m.d = 1; 
				}
			}
			else if (m.d == 3) { //좌
				m.c --; 
				if(lineCheck(m.c)) {
					m.n /=2; 
					m.d = 4; 
				}
			}
			else { // 우 
				m.c ++; 
				if(lineCheck(m.c)) {
					m.n /=2; 
					m.d = 3;
				} 
			}
				
			map[m.r][m.c] += m.n;  // 해당 행과 열 위치에 현재 미생물 값 누적
			
			if(microbeNumber[m.r][m.c]==-1) microbeNumber[m.r][m.c] = i; 
			// 현재 미생물 번호가 저장되어 있찌 않으면 저장. 
			else {
				// 이전에 미생물 번호가 저장되어 있으면 미생물이 지금 겹친다는 의미 
				Microbe prevMicrobe = microbeList.get(microbeNumber[m.r][m.c]); 
				// 이전 미생물 정보 들고와 
				if(prevMicrobe.n<m.n) {
					// 만약 이전 미생물 개수가 현재 미생물 보다 작다면 잡아 먹혀야지 
					prevMicrobe.isEaten = true; 
					// 이전 미생물 정보 중 잡아 먹혔다고 갱신 
					microbeNumber[m.r][m.c] = i; 
					// 현재 미생물 번호로 갱신하자 
				}		
				else {
					m.isEaten = true; 
					// 이전 미생물의 개수가 더 많다면 바로 잡아 먹혀야지 
				}
			}
		}
		
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				if(map[i][j]!=0) {
					// 미생물 개수가 0이 아니라면 
					microbeList.get(microbeNumber[i][j]).n = map[i][j]; 
					// map 위치 인덱스에 찍혀있는 미생물 번호를 들고와서 누적된 미생물 개수로 갱신해준다. 
				}
			}
		}
	}
	
	
	
	static class Microbe{
		
		int r; //행
		int c; //열
		int n; //개수
		int d; //방향
		boolean isEaten; //먹혔냐
		
		public Microbe(int r, int c, int n, int d, boolean isEaten) {
			super();
			this.r = r;
			this.c = c;
			this.n = n;
			this.d = d;
			this.isEaten = isEaten;
		} 
	}
	

}
 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

반응형

댓글