접근 방법
1. 핵심 로직 : 미생물을 모두 이동시킨 후에 합쳐질 수 있는 미생물에 대해 처리
2. 미생물이 충돌하는 경우(같은 좌표인 경우)에 대해 확인하기 위해 Collections.sort를 사용하여 같은 좌표에 대해 모여있을 수 있도록 하였습니다.
구현 설명
- LinkedList<Pair> locations : 미생물의 좌표를 저장하는 리스트입니다.
구현 시 주의 사항
- 리스트를 사용하면서 미생물을 처리하는 과정에서 remove함수를 사용하게 됩니다. 이때 인덱스에 대해서도 -1 해주어야 합니다. 그렇지 않으면, 처리하는 과정에서 일부 요소가 누락될 수 있습니다. List의 논리적 크기는 고정되어 있지 않으며, List에 있는 요소의 삽입이나 삭제에 따라 변경됩니다.
구현하며 어려웠던 점
- sort를 위해 compareto에서 조건으로 x좌표와 y좌표가 같은 경우에 대해 미생물 수를 기준으로 내림차순을 진행하였습니다. 그 외의 경우에 대해서는 x좌표 기준 오름차순을 진행하였습니다. 하지만, 이 과정에서 분명 x, y좌표가 같은 미생물 들임에도 불구하고 제대로 sort가 되지 않았습니다. 따라서, 추가적으로 x좌표가 같은 경우에 대해 y좌표 기준 오름차순을 진행을 통해 모든 좌표에 대해 제대로 sort가 이루어질 수 있었습니다.
package swea.p2382;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Solution_2382 {
private static int[][] dir = {{0, 0},{-1,0}, {1,0},{0,-1},{0,1}};//상하좌우
private static int result;
private static LinkedList<Pair> locations;
static class Pair implements Comparable<Pair>{
int x;
int y;
int value;//미생물 수
int move_dir;//이동방향, (상: 1, 하: 2, 좌: 3, 우: 4)
public Pair(int x, int y, int value, int move_dir) {
this.x = x;
this.y = y;
this.value = value;
this.move_dir = move_dir;
}
@Override
public int compareTo(Pair o) {
if(this.x==o.x && this.y == o.y) {
return -(this.value - o.value);
}
if(this.x == o.x)
return this.y - o.y;
return this.x - o.x;
}
@Override
public String toString() {
return "Pair [x=" + x + ", y=" + y + ", value=" + value + ", move_dir=" + move_dir + "]";
}
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int test_case = 1; test_case <= T; test_case++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());//셀의 개수
int M = Integer.parseInt(st.nextToken());//격리 시간
int K = Integer.parseInt(st.nextToken());//미생물 군집의 개수
locations = new LinkedList<Pair>();
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 size = Integer.parseInt(st.nextToken());
int direction = Integer.parseInt(st.nextToken());
locations.add(new Pair(x, y, size, direction));
}
solve(M, N);
System.out.println("#" + test_case + " " + result);
}
}
//로직 : 모든 미생물 이동시킨 후에 합쳐지는 미생물 처리하기
private static void solve(int M, int N) {
while(M-- > 0) {
for (int i = 0; i < locations.size(); i++) {
Pair now = locations.get(i);
int nowX = now.x;
int nowY = now.y;
int nowValue = now.value;
int nowDir = now.move_dir;
int nextX = nowX + dir[nowDir][0];
int nextY = nowY + dir[nowDir][1];
int nextDir = 0;
if(nextX == 0 || nextY == 0 || nextX >= N-1 || nextY >= N-1) {//약품이 칠해진 구역(가장 자리의 빨간 셀)
if(nowDir == 1) nextDir = 2;
else if(nowDir == 2) nextDir = 1;
else if(nowDir == 3) nextDir = 4;
else nextDir = 3;
now.move_dir = nextDir;
now.value /= 2;
if(now.value <= 0) {//미생물 죽음
locations.remove(i);
i--;
}else {
now.x = nextX;
now.y = nextY;
}
}else {
now.x = nextX;
now.y = nextY;
}
}
Collections.sort(locations);
//합쳐지는 미생물 처리하기
combine(locations);
}
result = count(locations);
}
//합쳐지는 미생물 처리하기
//같은 좌표에 대해 미생물 개수를 기준으로 내림차순-> 맨 앞의 좌표가 가장 개수가 크므로, 방향은 맨 앞을 기준으로 따름
private static void combine(LinkedList<Pair> temp) {
for (int i = 0; i < temp.size(); i++) {
int sum = temp.get(i).value;
int start = i;
//같은 좌표 미생물 찾기
while(i+1 < temp.size() && temp.get(i).x - temp.get(i+1).x == 0 && temp.get(i).y - temp.get(i+1).y == 0) {
sum += temp.get(i+1).value;
i++;
}
//합치기
//우선 순위에 따라 맨 앞의 요소가 방향이 큰 값이므로 방향에 대한 수정은 필요 X
temp.get(start).value = sum;
for (int j = start+1; j <= i; j++) {
temp.remove(j);
i--;
j--;
}
}
}
private static int count(LinkedList<Pair> temp) {
int sum = 0;
for (int i = 0; i < temp.size(); i++) {
sum += temp.get(i).value;
}
return sum;
}
}
'Algorithm > SWEA' 카테고리의 다른 글
[SWEA] 1952. [모의 SW 역량테스트] 수영장(자바/dfs) (0) | 2022.10.28 |
---|---|
[SWEA] 자바 1249. [S/W 문제해결 응용] 4일차 - 보급로 (0) | 2022.10.02 |
[SWEA] 4008번 [모의 SW 역량테스트] 숫자 만들기 - 자바 (0) | 2022.09.14 |
[SWEA] 7465 창용 마을 무리의 개수 - 자바 (0) | 2022.08.24 |
[SWEA] 자바 1247 최적경로 (0) | 2022.08.21 |