본문 바로가기

코딩테스트/JAVA

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

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV597vbqAH0DFAVl

 

SW Expert Academy

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

swexpertacademy.com

 

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

public class Solution {
	public static int T, N, K, M, ans;
	public static int[][] map;
	public static int[] dx = { -1, 1, 0, 0 };
	public static int[] dy = { 0, 0, -1, 1 };
	public static List<Vir> list;

	public static class Vir {
		int x;
		int y;
		int num;
		int dir;

		public Vir(int x, int y, int num, int dir) {
			super();
			this.x = x;
			this.y = y;
			this.num = num;
			this.dir = dir;
		}
	}

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		T = Integer.parseInt(st.nextToken());

		for (int tc = 1; tc <= T; tc++) {
			// 1. 입력값 받기
			st = new StringTokenizer(br.readLine());
			
			// 1-1. N, M, K 입력 받기
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			K = Integer.parseInt(st.nextToken());
			
			// 1-2. map, list, ans 초기화
			// map = new int[N][N];
			list = new ArrayList<>();
			ans = 0;
			
			// 1-3. vir 입력 받기 (map에 군집수 넣기)
			for (int i = 0; i < K; i++) {
				st = new StringTokenizer(br.readLine());
				int x = Integer.parseInt(st.nextToken());
				int y = Integer.parseInt(st.nextToken());
				int num = Integer.parseInt(st.nextToken());
				int dir = Integer.parseInt(st.nextToken());
				list.add(new Vir(x, y, num, dir));
			}
			// 2. M 만큼 반복
			for (int i = 0; i < M; i++) {
				// 리스트를 sort를 해주긴 해야겠다. 그러면 객체로 만들어야해?
				list.sort((o1, o2) -> Integer.compare(o1.num, o2.num));
				// map을 계속 초기화 해야겠는데?
				map = new int[N][N];
				
				// 2-1. 겹치는 부분이 있는지 확인? 다돌고 확인? 갈때마다 확인 이동했는지 안했는지 어떻게 알아?
				for (int j = list.size() - 1; j >= 0; j--) {
					Vir v = list.get(j);
					//System.out.println(v.x + " " + v.y + " " + v.num + " " + v.dir);
					int nx = v.x + dx[v.dir - 1];
					int ny = v.y + dy[v.dir - 1];
					if (nx == 0 || ny == 0 || nx == N - 1 || ny == N - 1) {
						int ndir = 0;
						switch (v.dir) {
						case 1:
							ndir = 2;
							break;
						case 2:
							ndir = 1;
							break;
						case 3:
							ndir = 4;
							break;
						case 4:
							ndir = 3;
							break;
						}
						
						list.set(j, new Vir(nx, ny, v.num / 2, ndir));
						map[nx][ny] = v.num / 2;
						continue;
					}

					if (map[nx][ny] > 0) { // 세포가 겹쳤다면
						map[nx][ny] += v.num;
						
						list.remove(j);
					} else {
						map[nx][ny]= v.num;
						list.set(j, new Vir(nx, ny, v.num, v.dir));
					}

				}
				
				for (int j = 0; j < list.size(); j++) {
					Vir v = list.get(j);
					if(map[v.x][v.y] != v.num) {
						list.set(j, new Vir(v.x, v.y, map[v.x][v.y], v.dir));
					}
				}

			}

			// 3. map 에 있는 군집수 모두 더한 후 출력
			for (int i = 0; i < list.size(); i++) {
				ans += list.get(i).num;
			}

			System.out.println("#" + tc + " " + ans);
		}

	}

}

 


풀이 사항
풀이 일자: 2024.08.27
풀이 시간: 100분 00초
채점 결과: 정답
예상 문제 유형: 구현

 

풀이 방법

이전에 올린 줄기 세포 배양이랑 비슷한 방법으로 풀이했다. 

 

1. 삽입은 안돼지만 합쳐지는 군집이 있으므로 이를 리스트로 다루는게 좋다고 생각했다. 또한 리스트를 정렬하고 싶었기 때문에 객체를 넣을 수 있는 리스트를 만들어서 객체의 원소를 기준으로 정렬할 수 있게 만들어 주었다.

 

2. 입력을 받고 군집도 입력을 받는다. 

 

3. M일만큼 반복하며 map과 list를 정렬해주고 삭제연산이 이루어지기 뒤부터 탐색해주었다.

 

4. 끝에 닿았다면 크기 반 줄이고 방향 바꿔주기

 

5. 세포가 겹쳤다면 어차피 수가 큰 군집부터 들어갔기 때문에 나중에 들어온것이 작은것이다.

따라서 맵의 크기만 증가시키고 리스트에서 군집을 삭제시킨다.

 

6. 겹치지 않는다면 위치만 바꾸어 리스트 바꿔주기

 

7. 마지막에 세포가 합쳐지며 크기가 커진 군집도 있을 수 있으므로 검사해준다.

 

맨처음에 어이없게 K값을 잘못보고 테케를 잘못넣어주어서 계속 StringToknizer 오류가 발생했다.

 

테케를 잘 보고 잘 넣자. 또한 끝에 닿았을때 반줄인것을 맵에 넣어주어야하는데 소홀히 안넣었더니 또 오류

 

마지막으로 마지막에 닿을때 N-1 인데 N으로 넣어서 오류 끝