파핑파핑 지뢰찾기
in Algorithm on SW Expert Academy
SW Expert Academy [1868] 파핑파핑 지뢰찾기
풀이
- aroundChk() : 8면에 지뢰가 있는지 확인하고 지뢰가 없으면 큐에 담고, 있으면 지뢰 갯수를 memo 배열에 저장
- cntPoping() : aroundChk()를 통해 큐에 담겨진 것이 이전에 poping 되면 중복되므로 잘 체크하고, memo에서 0으로 기록된 곳은 다시 방문
소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
public class Solution {
static int N, ans, dotCnt;
static char[][] map;
static int[][] memo;
static Queue<int[]> poping;
static int[] dx = { 0, 0, -1, 1, -1, -1, 1, 1 };
static int[] dy = { -1, 1, 0, 0, -1, 1, -1, 1 };
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
N = Integer.parseInt(br.readLine());
map = new char[N][N];
memo = new int[N][N];
dotCnt = 0;
for (int i = 0; i < N; i++) {
String str = br.readLine();
for (int j = 0; j < N; j++) {
map[i][j] = str.charAt(j);
if (map[i][j] == '.')
dotCnt++;
}
}
ans = 0;
Queue<int[]> q = aroundChk();
if (q.size() > 0) {
poping = new LinkedList<>();
cntPoping(q, false);
ans += dotCnt;
} else
ans = dotCnt;
System.out.println("#" + tc + " " + ans);
}
}
static Queue<int[]> aroundChk() {
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (map[i][j] == '*')
continue;
boolean flag = false;
int idx = 0;
int cnt = 0;
while (idx < 8) {
int x = i + dx[idx];
int y = j + dy[idx];
if (isRange(x, y) && map[x][y] == '*') {
flag = true;
cnt++;
}
idx++;
}
if (!flag) {
queue.add(new int[] { i, j });
}
memo[i][j] = cnt;
}
}
return queue;
}
static void cntPoping(Queue<int[]> q, boolean flag) {
while (!q.isEmpty() && dotCnt > 0) {
int[] point = q.poll();
if (map[point[0]][point[1]] != '.') // 숫자로 바뀐경우
continue;
dotCnt--;
if (!flag)
ans++;
map[point[0]][point[1]] = '0';
for (int k = 0; k < 8; k++) {
int x = point[0] + dx[k];
int y = point[1] + dy[k];
if (isRange(x, y) && map[x][y] == '.') {
if (memo[x][y] == 0)
poping.add(new int[] { x, y });
else {
map[x][y] = Character.forDigit(memo[x][y], 10);
dotCnt--;
}
}
}
while (!poping.isEmpty()) {
cntPoping(poping, true);
}
}
}
static boolean isRange(int x, int y) {
return x >= 0 && y >= 0 && x < N && y < N;
}
}