[SWEA] 5653. 줄기세포배양
- 메모리 : 94,044 KB
- 실행시간 : 345 ms
- 코드길이 : 2,955 B
- 소요시간 : 1H
- 문제에서 말한 것을 그대로 BFS로 구현하는 것 자체도 꽤 까다로웠다. 비활성 상태의 세포도 고려해야하고 세포마다 퍼지는 시간이 달라서 이 모든 것을 생각하고 처리해주어야 했다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Solution_5653_줄기세포배양 {
static int size = 400, N, M, K, res;
static int[][] map;
static List<ArrayList<Data>> cells;
static int[][] delta = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } }; // 상 우 하 좌
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
StringBuilder answer = new StringBuilder();
int TC = Integer.parseInt(in.readLine());
for (int t = 1; t <= TC; t++) {
st = new StringTokenizer(in.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new int[size][size];
cells = new ArrayList<>();
res = 0;
for (int i = 0; i < 10; i++) {
cells.add(new ArrayList<Data>());
}
for (int i = size / 2; i < N + size / 2; i++) {
st = new StringTokenizer(in.readLine(), " ");
for (int j = size / 2; j < M + size / 2; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
if (map[i][j] > 0)
cells.get(map[i][j] - 1).add(new Data(i, j, map[i][j], map[i][j], K, false));
}
}
bfs();
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (map[i][j] > 0)
res++;
}
}
answer.append('#').append(t).append(' ').append(res).append('\n');
} // end test-case
System.out.println(answer);
} // end main
private static void bfs() {
Queue<Data> queue = new LinkedList<Data>();
for (int i = 9; i >= 0; i--) {
if (cells.get(i).size() > 0) {
for (Data data : cells.get(i)) {
queue.offer(data);
}
}
} // end for cells
Data cur;
while (!queue.isEmpty()) {
cur = queue.poll();
if (cur.life == 0 && cur.isActive) {
map[cur.i][cur.j] = -1;
continue;
}
if (cur.k == 0)
continue;
if (cur.life > 0) {
queue.offer(new Data(cur.i, cur.j, cur.x, cur.life - 1, cur.k - 1, cur.isActive));
continue;
}
queue.offer(new Data(cur.i, cur.j, cur.x, cur.x, cur.k, true));
for (int d = 0; d < delta.length; d++) {
int curX = cur.i + delta[d][0];
int curY = cur.j + delta[d][1];
if (map[curX][curY] == 0) {
map[curX][curY] = cur.x;
queue.offer(new Data(curX, curY, cur.x, cur.x, cur.k - 1, false));
}
}
} // end while
} // end bfs
static class Data {
int i;
int j;
int x; // 줄기세포 생명력
int life; // 줄기세포 생명력
int k; // 배양시간 K
boolean isActive; // 활성상태 ture, 비활성상태 false
public Data(int i, int j, int x, int life, int k, boolean isActive) {
this.i = i;
this.j = j;
this.x = x;
this.life = life;
this.k = k;
this.isActive = isActive;
}
}
}
Priority Queue
- 메모리 : 47,372 KB
- 실행시간 : 207 ms
- 코드길이 : 2,350 B
- 소요시간 : 40M
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Solution_5653_줄기세포배양_PQ {
static int size = 400, N, M, K, res;
static boolean[][] visited;
static PriorityQueue<Data> cells;
static int[][] delta = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } }; // 상 우 하 좌
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = null;
StringBuilder answer = new StringBuilder();
int TC = Integer.parseInt(in.readLine());
for (int t = 1; t <= TC; t++) {
st = new StringTokenizer(in.readLine(), " ");
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
visited = new boolean[size][size];
cells = new PriorityQueue<Data>();
res = 0;
for (int i = size / 2; i < N + size / 2; i++) {
st = new StringTokenizer(in.readLine(), " ");
for (int j = size / 2; j < M + size / 2; j++) {
int x = Integer.parseInt(st.nextToken());
if (x > 0) {
visited[i][j] = true;
cells.offer(new Data(i, j, x, x + 1));
if (x * 2 > K) res++; // K시간보다 크면 비활성상태일 것이기 때문에 미리 카운트
}
}
}
bfs();
answer.append('#').append(t).append(' ').append(res).append('\n');
} // end test-case
System.out.println(answer);
} // end main
private static void bfs() {
int time = 0;
Data cur;
while (time <= K) {
cur = cells.poll();
time = cur.time;
if (time > K) break;
for (int d = 0; d < delta.length; d++) {
int curX = cur.i + delta[d][0];
int curY = cur.j + delta[d][1];
if (!visited[curX][curY]) {
visited[curX][curY] = true;
cells.offer(new Data(curX, curY, cur.x, time + cur.x + 1));
if (time + cur.x * 2 > K) res++;
}
}
}
} // end bfs
static class Data implements Comparable<Data> {
int i;
int j;
int x; // 줄기세포 생명력
int time; // 활성화 시간
public Data(int i, int j, int x, int time) {
this.i = i;
this.j = j;
this.x = x;
this.time = time;
}
@Override
public int compareTo(Data o) {
if (time != o.time) return Integer.compare(time, o.time);
return -Integer.compare(x, o.x);
}
}
}
Leave a comment