https://www.acmicpc.net/problem/4396
4396번: 지뢰 찾기
지뢰찾기는 n × n 격자 위에서 이루어진다. m개의 지뢰가 각각 서로 다른 격자 위에 숨겨져 있다. 플레이어는 격자판의 어느 지점을 건드리기를 계속한다. 지뢰가 있는 지점을 건드리면 플레이어
www.acmicpc.net
풀이
간단한 구현 문제다.
지뢰의 위치와 게임판을 입력받은 다음, 게임판에서 열린 칸(x표시)마다 주변에 지뢰가 몇 개 있는지 카운트하고 그 값을 따로 배열에 저장하여 출력한다.
하지만 "지뢰가 있는 칸이 열렸다면 지뢰가 있는 모든 칸이 별표(*)로 표시되어야 한다." 그래서 열린 칸이 지뢰인 경우를 따로 체크하여 이후 정답을 출력하기 전 지뢰가 있는 모든 칸을 별표로 표시하고 출력해야 한다.
코드
import java.io.*;
public class Main {
// 8개의 방향을 나타내는 방향 배열
static int[] dx = {0, 1, 1, 1, 0, -1, -1, -1};
static int[] dy = {1, 1, 0, -1, -1, -1, 0, 1, 1};
// 인덱스가 배열의 범위를 벗어나지 않으면 true, 벗어나면 false 리턴
public static boolean check(int x, int y, int n) {
if (x >= 0 && x < n && y >= 0 && y < n)
return true;
else
return false;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
String[] bomb = new String[n]; // 지뢰의 위치
String[] game = new String[n]; // 게임판
for (int i = 0; i < n; i++) {
bomb[i] = br.readLine();
}
for (int i = 0; i < n; i++) {
game[i] = br.readLine();
}
char[][] answer = new char[n][n]; // 정답을 저장하는 배열
boolean fail = false; // 지뢰를 밟으면 true로 바뀜
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (game[i].charAt(j) == 'x') {
int cnt = 0;
// 현재 위치에 지뢰가 몇 개 있는지 카운트
for (int k = 0; k < 8; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if (check(nx, ny, n) && bomb[nx].charAt(ny) == '*')
cnt++;
}
answer[i][j] = (char)(cnt + '0');
// 지뢰를 밟은 경우
if (bomb[i].charAt(j) == '*')
fail = true;
}
else
answer[i][j] = '.';
}
}
StringBuilder sb = new StringBuilder();
// 지뢰를 밟으면 지뢰가 있는 모든 칸이 별표(*)로 표시되어야 한다
if (fail) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (bomb[i].charAt(j) == '*')
answer[i][j] = '*';
}
}
}
// 정답 출력
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sb.append(answer[i][j]);
}
sb.append("\n");
}
System.out.println(sb);
}
}
- answer[i][j] = (char)(cnt + '0');
- 숫자를 문자로 변환
다른 풀이 2
위의 풀이에서는 bomb, game, answer 3개의 변수를 사용해서 각각 지뢰의 위치, 게임판, 정답의 정보를 저장했다. 하지만 하나의 변수만으로도 문제를 해결할 수 있다.
char[][] game에 지뢰의 위치를 저장하고, 게임판에서 열린 칸(x표시)마다 주변에 지뢰가 몇 개 있는지 카운트한다. 이 때 지뢰가 있는 위치의 값은 변하지 말아야 한다.
그리고 지뢰를 밟지 않은 경우 지뢰가 있는 위치는 별표로 그대로 남아있으므로 온점(.)으로 바꾸어 주어야 한다.
정답을 출력할 때도 game을 출력하면 된다.
import java.io.*;
public class Main {
// 8개의 방향을 나타내는 방향 배열
static int[] dx = {0, 1, 1, 1, 0, -1, -1, -1};
static int[] dy = {1, 1, 0, -1, -1, -1, 0, 1, 1};
// 인덱스가 배열의 범위를 벗어나지 않으면 true, 벗어나면 false 리턴
public static boolean check(int x, int y, int n) {
if (x >= 0 && x < n && y >= 0 && y < n)
return true;
else
return false;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
char[][] game = new char[n][n]; // 지뢰의 위치
for (int i = 0; i < n; i++) {
String str = br.readLine();
game[i] = str.toCharArray();
}
boolean fail = false; // 지뢰를 밟으면 true로 바뀜
for (int i = 0; i < n; i++) {
String str = br.readLine();
for (int j = 0; j < n; j++) {
if (str.charAt(j) == 'x') {
// 지뢰를 밟은 경우
if (game[i][j] == '*') {
fail = true;
continue;
}
int cnt = 0;
// 현재 위치에 지뢰가 몇 개 있는지 카운트
for (int k = 0; k < 8; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if (check(nx, ny, n) && game[nx][ny] == '*')
cnt++;
}
game[i][j] = (char)(cnt + '0');
}
}
}
StringBuilder sb = new StringBuilder();
// 지뢰를 밟지 않은 경우 지뢰가 있는 곳을 온점으로 바꾸어주어야 한다.
if (!fail) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (game[i][j] == '*')
game[i][j] = '.';
}
}
}
// 정답 출력
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
sb.append(game[i][j]);
}
sb.append("\n");
}
System.out.println(sb);
}
}
- game[i] = str.toCharArray();
- 문자열을 char 배열로 변환
728x90
'Algorithm 문제 풀이 > 백준' 카테고리의 다른 글
[백준] 1759번 : 암호 만들기 - 자바[Java] (0) | 2022.09.09 |
---|---|
[백준] 1244번 : 스위치 켜기 - 자바[Java] (0) | 2022.09.09 |
[백준] 2578번 : 빙고 - 자바[Java] (0) | 2022.09.09 |
[백준] 14476번 : 소가 길을 건너간 이유 1 - 자바[Java] (0) | 2022.09.08 |
이전 블로그의 알고리즘 문제 풀이 모음 (0) | 2022.09.08 |