N = Integer.parseInt(bf.readLine());
color = new String[N][N];
//색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
color[i] = bf.readLine().split("");
}
public static int howManyIsLands(int[][] map, boolean[][] visited) {
int count = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
if (map[i][j] == 1 && !visited[i][j]) {
dfs(map, visited, i, j);
count++;
}
}
}
return count;
}public static void dfs(int[][] map, boolean[][] visited, int i, int j) {
stack.push(new int[]{i, j});
visited[i][j] = true;
while (!stack.isEmpty()) {
int[] current = stack.pop(); // {0, 0}
int dx = current[0];
int dy = current[1];
for (int k = 0; k < dX.length; k++) {
int x = dx + dX[k];
int y = dy + dY[k];
if (x >= 0 && y >= 0 && x < h && y < w && map[x][y] == 1 && !visited[x][y]) {
stack.push(new int[]{x, y});
visited[x][y] = true;
}
}
}
}배열 초기화에 있어서..
처음에 그냥 색깔 배열을 2차원으로 초기화해서 사용하면 되기 때문에 정말 단순하게 아래와 같이 코드를 짰다.
//색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
char[] charArray = bf.readLine().toCharArray();
for (int j = 0; j < N; j++) {
color[i][j] = String.valueOf(charArray[j]);
}
}
그런데 뭔가 너무 불필요한 코드들이 많은 것 같기도 하고 굳이 2중 for문을 쓸 필요가 없는데, 너무 무지성으로 빨리 한 느낌..?
그래서 리팩토링 할 때 배열 초기화 코드를 아래와 같이 바꿨다.
//색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
color[i] = bf.readLine().split("");
}
훨씬 코드가 간단해졌고, 머리속으로는 아는 코드이지만 이걸 빨리 구현하려는 생각 때문에 너무 직관적으로 돌아간 것 같다. 해당 방식을 조금 잘 기억해보자..앞으로…초기화할 때
그리고 처음에는 적록색약이 아닌 사람과 적록색약인 사람의 메소드를 분리하였었다.
이렇게 분리에 포커스를 맞춰서 구현하다보니 BFS 메소드 조차 분리하여 코드의 양이 길어지는 단점이 발생하였다.
package BOJ_10026;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.*;
public class BOJ_10026 {
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static int N;
static String[][] color;
static boolean[][] visited;
static Queue<int[]> queue = new LinkedList<>();
static int[] dX = new int[]{0, 0, 1, -1};
static int[] dY = new int[]{1, -1, 0, 0};
public static void main(String[] args) throws IOException{
N = Integer.parseInt(bf.readLine());
color = new String[N][N];
//색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
color[i] = bf.readLine().split("");
}
int countNormal = checkNormal();
int countAbnormal = checkAbNormal();
System.out.println(countNormal + " " + countAbnormal);
}
public static int checkNormal() {
int count = 0;
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
bfs_Normal(i, j);
count++;
}
}
}
return count;
}
public static int checkAbNormal() {
int count = 0;
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
bfs_Abnormal(i, j);
count++;
}
}
}
return count;
}
public static void bfs_Normal(int x, int y) {
queue.add(new int[]{x, y});
visited[x][y] = true;
while (!queue.isEmpty()) {
int[] current = queue.poll();
int dx = current[0];
int dy = current[1];
for (int k = 0; k < dX.length; k++) {
int a = dx + dX[k];
int b = dy + dY[k];
if (a >= 0 && b >= 0 && a < N && b < N && !visited[a][b] && color[a][b].equals(color[x][y])) {
queue.add(new int[]{a, b});
visited[a][b] = true;
}
}
}
}
public static void bfs_Abnormal(int x, int y) {
queue.add(new int[]{x, y});
visited[x][y] = true;
while (!queue.isEmpty()) {
int[] current = queue.poll();
int dx = current[0];
int dy = current[1];
for (int k = 0; k < dX.length; k++) {
int a = dx + dX[k];
int b = dy + dY[k];
if (a >= 0 && b >= 0 && a < N && b < N && !visited[a][b]) {
if (color[a][b].equals(color[x][y]) || validColor(color[x][y], color[a][b])) {
queue.add(new int[]{a, b});
visited[a][b] = true;
}
}
}
}
}
public static boolean validColor(String startColor, String comparedColor) {
if (startColor.equals("R") && comparedColor.equals("G")) {
return true;
} else if (startColor.equals("G") && comparedColor.equals("R")) {
return true;
} else return false;
}
}
public class BOJ_10026 {
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static int N;
static String[][] color;
static boolean[][] visited;
static final int[] dX = {0, 0, 1, -1};
static final int[] dY = {1, -1, 0, 0};
public static void main(String[] args) throws IOException {
N = Integer.parseInt(bf.readLine());
color = new String[N][N];
// 색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
color[i] = bf.readLine().split("");
}
int countNormal = countRegions(false);
int countAbnormal = countRegions(true);
System.out.println(countNormal + " " + countAbnormal);
}
public static int countRegions(boolean isColorBlind) {
int count = 0;
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
bfs(i, j, isColorBlind);
count++;
}
}
}
return count;
}
public static void bfs(int x, int y, boolean isColorBlind) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{x, y});
visited[x][y] = true;
String startColor = color[x][y];
while (!queue.isEmpty()) {
int[] current = queue.poll();
int a = current[0];
int b = current[1];
for (int k = 0; k < dX.length; k++) {
int dx = a + dX[k];
int dy = b + dY[k];
if (dx >= 0 && dy >= 0 && dx < N && dy < N && !visited[dx][dy]) {
if (isSameColor(startColor, color[dx][dy], isColorBlind)) {
queue.add(new int[]{dx, dy});
visited[dx][dy] = true;
}
}
}
}
}
public static boolean isSameColor(String color1, String color2, boolean isColorBlind) {
if (isColorBlind && (color1.equals("R") || color1.equals("G"))) {
return color2.equals("R") || color2.equals("G");
}
return color1.equals(color2);
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.*;
public class BOJ_10026 {
static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
static int N;
static String[][] color;
static boolean[][] visited;
static final int[] dX = {0, 0, 1, -1};
static final int[] dY = {1, -1, 0, 0};
public static void main(String[] args) throws IOException {
N = Integer.parseInt(bf.readLine());
color = new String[N][N];
// 색깔 2차원 배열 초기화
for (int i = 0; i < N; i++) {
color[i] = bf.readLine().split("");
}
int countNormal = countRegions(false);
int countAbnormal = countRegions(true);
System.out.println(countNormal + " " + countAbnormal);
}
public static int countRegions(boolean isColorBlind) {
int count = 0;
visited = new boolean[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
bfs(i, j, isColorBlind);
count++;
}
}
}
return count;
}
public static void bfs(int x, int y, boolean isColorBlind) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{x, y});
visited[x][y] = true;
String startColor = color[x][y];
while (!queue.isEmpty()) {
int[] current = queue.poll();
int a = current[0];
int b = current[1];
for (int k = 0; k < dX.length; k++) {
int dx = a + dX[k];
int dy = b + dY[k];
if (dx >= 0 && dy >= 0 && dx < N && dy < N && !visited[dx][dy]) {
if (isSameColor(startColor, color[dx][dy], isColorBlind)) {
queue.add(new int[]{dx, dy});
visited[dx][dy] = true;
}
}
}
}
}
public static boolean isSameColor(String color1, String color2, boolean isColorBlind) {
if (isColorBlind && (color1.equals("R") || color1.equals("G"))) {
return color2.equals("R") || color2.equals("G");
}
return color1.equals(color2);
}
}
이 코드의 전체 시간 복잡도는 O(N^2)
N의 값이 커져도 N^2의 크기에 비례하여 수행 시간은 선형적으로 증가함
N이 최대 100이므로 최악의 경우에도 10000 번의 연산으로 충분히 처리할 수 있음
나야 들기름