728x90
반응형
2024.08.09기준 - 골드5
백준, BEAKJOON, BOJ, JAVA, 자바
풀이
이 문제는 RGB가 주어 졌을 때, 일반인이라면 몇 구역으로 보고, 적록색약이라면 몇 구역으로 보는지 출력하는 문제입니다.
1. 모든 그리드를 전부 탐색하기 위해 위, 오른쪽, 아래, 왼쪽 좌표로 이동할 수 있는 배열을 생성했습니다.
static int[] dx = {0, 1, 0, -1}; // 위, 오른쪽, 아래, 왼쪽
static int[] dy = {-1, 0, 1, 0};
2. 한 번 확인한 곳은 체크를 하기 위해 boolean[][] visit를 일반인과 적록색약으로 각각 생성했습니다.
map = new char[n][n]; // RGB를 저장할 배열
orivisit = new boolean[n][n]; // 일반인
rgvisit = new boolean[n][n]; // 적록색약
3. 하나 하나의 그리드를 체크하면서 체크가 되어 있지 않다면, 해당하는 범위를 체크하는 함수를 호출합니다.
int oricount = 0, rgcount = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!orivisit[i][j]) { // 아직 체크 되지 않았다면
oricount++;
ori(i, j);
}
if (!rgvisit[i][j]) { // 아직 체크 되지 않았다면
rgcount++;
rg(i, j);
}
}
}
호출함과 동시에 count수를 올려줍니다.
4. 위, 아래, 양 옆을 확인할 때, 그리드를 벗어나지 않도록 함수를 생성해주었습니다.
// map범위를 벗어나지 않도록 체크해주는 함수.
private static boolean check(int y, int x) {
return x >= 0 && y >= 0 && x < n && y < n;
}
5. 일반일때 하나의 범위를 체크하는 함수를 생성합니다.
// 일반인이 볼 때 하나로 보는 범위를 체크해주는 함수.
private static void ori(int y, int x) {
Queue<Integer> yqu = new LinkedList<>();
Queue<Integer> xqu = new LinkedList<>();
yqu.add(y);
xqu.add(x);
orivisit[y][x] = true;
int nowy, nowx, nexty, nextx;
while (!yqu.isEmpty()) {
nowy = yqu.poll();
nowx = xqu.poll();
for (int i = 0; i < 4; i++) {
nexty = nowy + dy[i];
nextx = nowx + dx[i];
// map 범위를 벗어나지 않으면서 아직 확인을 안한 구역이면서, 참조하는 색상과 같다면 true
if (check(nexty, nextx) && !orivisit[nexty][nextx] && map[nexty][nextx] == map[nowy][nowx]) {
orivisit[nexty][nextx] = true;
yqu.add(nexty);
xqu.add(nextx);
}
}
}
}
- 처음 들어온 좌표를 생성한 큐에다가 x, y좌표를 입력하여 visit를 체크해줍니다.
- 위, 아래. 양옆을 체크하기 위해 생성된 배열을 반복문으로 돌려주며 해당하는 좌표를 체크해줍니다.
- check함수와 아직 참조하지 않았는지, 현재 좌표에 해당하는 RGB와 같은지를 체크해 같다면 true, 큐에다가 좌표를 추가해줍니다.
6. 적록색약일 때 하나의 범위를 체크해주는 함수를 생성합니다.
// 적록색약인이 볼 때 하나로 보는 범위를 체크해주는 함수.
private static void rg(int y, int x) {
Queue<Integer> yqu = new LinkedList<>();
Queue<Integer> xqu = new LinkedList<>();
yqu.add(y);
xqu.add(x);
rgvisit[y][x] = true;
int nowy, nowx, nexty, nextx;
while (!yqu.isEmpty()) {
nowy = yqu.poll();
nowx = xqu.poll();
for (int i = 0; i < 4; i++) {
nexty = nowy + dy[i];
nextx = nowx + dx[i];
// map 범위를 벗어나지 않으면서 아직 확인을 안한 구역이라면
if (check(nexty, nextx) && !rgvisit[nexty][nextx]) {
// RG를 참조하고 들어온다면 RG일 때 true, G를 참조하고 있다면 G만 true
if (((map[nowy][nowx] == 'R' || map[nowy][nowx] == 'G') && (map[nexty][nextx] == 'R' || map[nexty][nextx] == 'G')) || (map[nowy][nowx] == 'B' && map[nexty][nextx] == 'B')) {
rgvisit[nexty][nextx] = true;
yqu.add(nexty);
xqu.add(nextx);
}
}
}
}
}
- 함수를 호출한 좌표를 visit를 true로 한 뒤에 qu에 다가 추가해줍니다.
- 추가된 좌표를 기준으로 위, 아래, 양 옆을 확인하는 반복문을 돌려줍니다.
- 다음 좌표들이 그리드 안에 있으면서, 한 번도 체크되지 않고, RG일 떄 RG, B일 때 B이면 해당하는 좌표를 큐에 추가 하며 true로 체크해줍니다.
코드
package Main;
import java.io.*;
import java.util.*;
public class Main {
static int[] dx = {0, 1, 0, -1}; // 위, 오른쪽, 아래, 왼쪽
static int[] dy = {-1, 0, 1, 0};
static int n;
static char[][] map;
static boolean[][] orivisit, rgvisit;
public static void main(String[] args) throws IOException { // ○
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
n = Integer.parseInt(br.readLine()); // 크기
map = new char[n][n]; // RGB를 저장할 배열
orivisit = new boolean[n][n]; // 일반인
rgvisit = new boolean[n][n]; // 적록색약
char[] arr;
for (int i = 0; i < n; i++) {
arr = br.readLine().toCharArray();
for (int j = 0; j < n; j++) {
map[i][j] = arr[j];
}
}
int oricount = 0, rgcount = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (!orivisit[i][j]) { // 아직 체크 되지 않았다면
oricount++;
ori(i, j);
}
if (!rgvisit[i][j]) { // 아직 체크 되지 않았다면
rgcount++;
rg(i, j);
}
}
}
sb.append(oricount).append(" ").append(rgcount);
bw.write(sb.toString());
bw.flush();
bw.close();
br.close();
}
// 적록색약인이 볼 때 하나로 보는 범위를 체크해주는 함수.
private static void rg(int y, int x) {
Queue<Integer> yqu = new LinkedList<>();
Queue<Integer> xqu = new LinkedList<>();
yqu.add(y);
xqu.add(x);
rgvisit[y][x] = true;
int nowy, nowx, nexty, nextx;
while (!yqu.isEmpty()) {
nowy = yqu.poll();
nowx = xqu.poll();
for (int i = 0; i < 4; i++) {
nexty = nowy + dy[i];
nextx = nowx + dx[i];
// map 범위를 벗어나지 않으면서 아직 확인을 안한 구역이라면
if (check(nexty, nextx) && !rgvisit[nexty][nextx]) {
// RG를 참조하고 들어온다면 RG일 때 true, G를 참조하고 있다면 G만 true
if (((map[nowy][nowx] == 'R' || map[nowy][nowx] == 'G') && (map[nexty][nextx] == 'R' || map[nexty][nextx] == 'G')) || (map[nowy][nowx] == 'B' && map[nexty][nextx] == 'B')) {
rgvisit[nexty][nextx] = true;
yqu.add(nexty);
xqu.add(nextx);
}
}
}
}
}
// 일반인이 볼 때 하나로 보는 범위를 체크해주는 함수.
private static void ori(int y, int x) {
Queue<Integer> yqu = new LinkedList<>();
Queue<Integer> xqu = new LinkedList<>();
yqu.add(y);
xqu.add(x);
orivisit[y][x] = true;
int nowy, nowx, nexty, nextx;
while (!yqu.isEmpty()) {
nowy = yqu.poll();
nowx = xqu.poll();
for (int i = 0; i < 4; i++) {
nexty = nowy + dy[i];
nextx = nowx + dx[i];
// map 범위를 벗어나지 않으면서 아직 확인을 안한 구역이면서, 참조하는 색상과 같다면 true
if (check(nexty, nextx) && !orivisit[nexty][nextx] && map[nexty][nextx] == map[nowy][nowx]) {
orivisit[nexty][nextx] = true;
yqu.add(nexty);
xqu.add(nextx);
}
}
}
}
// map범위를 벗어나지 않도록 체크해주는 함수.
private static boolean check(int y, int x) {
return x >= 0 && y >= 0 && x < n && y < n;
}
}
728x90
반응형
'코딩테스트 일기 (BAEKJOON)' 카테고리의 다른 글
BEAKJOON / 백준 - JAVA 16928번 뱀과 사다리 게임 (0) | 2024.08.10 |
---|---|
BEAKJOON / 백준 - JAVA 32076번 Easy as ABC (0) | 2024.08.09 |
BEAKJOON / 백준 - JAVA 32090번 シンプルなエディタ (0) | 2024.08.09 |
BEAKJOON / 백준 - JAVA 32089번 部員の変遷 (0) | 2024.08.09 |
BEAKJOON / 백준 - JAVA 28419번 더하기 (0) | 2024.08.08 |