ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Baekjoon Online Judge] 1080번: 행렬
    문제 풀이/Baekjoon Online Judge 2021. 1. 1. 18:09

    [Baekjoon Online Judge] 1080번: 행렬

     

    1080번: 행렬

    첫째 줄에 행렬의 크기 N M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에는 행렬 A가 주어지고, 그 다음줄부터 N개의 줄에는 행렬 B가 주어진다.

    www.acmicpc.net

     행렬B를 탐색하면서 행렬A와 비교한 값이 다를 때 행렬A를 변환하는 연산(어떤 3 x 3 크기의 부분 행렬에 있는 모든 원소를 뒤집는 것)의 최솟값을 구하는 문제이다.

     

    import java.io.*;
    
    public class Baekjoon1080 {
    
        public static BufferedReader bufferedReader;
        public static BufferedWriter bufferedWriter;
    
        public static int[][] matrixA;
        public static int[][] matrixB;
    
        public static void setMatrix(int[][] matrix, int n, int m) throws IOException {
            for (int i = 0; i < n; i++) {
                String[] rows = bufferedReader.readLine().split("");
                for (int j = 0; j < m; j++) {
                    matrix[i][j] = Integer.parseInt(rows[j]);
                }
            }
        }
    
        public static void reverse(int[][] matrix, int row, int col) {
            for (int i = row; i < row + 3; i++) {
                for (int j = col; j < col + 3; j++) {
                    if (matrix[i][j] == 1) {
                        matrix[i][j] = 0;
                    } else if (matrix[i][j] == 0) {
                        matrix[i][j] = 1;
                    }
                }
            }
        }
    
        public static boolean IsSameMatrix() {
            for (int i = 0; i < matrixA.length; i++) {
                for (int j = 0; j < matrixA[0].length; j++) {
                    if (matrixA[i][j] != matrixB[i][j]) {
                        return false;
                    }
                }
            }
            return true;
        }
    
        public static void print(int[][] matrix) {
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[0].length; j++) {
                    System.out.printf("%2d", matrix[i][j]);
                }
                System.out.println();
            }
            System.out.println();
        }
    
        public static void main(String[] args) throws IOException {
    
            bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
    
            String[] inputSplit = bufferedReader.readLine().split(" ");
            int n = Integer.parseInt(inputSplit[0]);
            int m = Integer.parseInt(inputSplit[1]);
    
            matrixA = new int[n][m];
            matrixB = new int[n][m];
    
            setMatrix(matrixA, n, m);
            setMatrix(matrixB, n, m);
    
            int count = 0;
            for (int i = 0; i <= n - 3; i++) {
                for (int j = 0; j <= m -3; j++) {
                    if (matrixA[i][j] == matrixB[i][j]) continue;
                    ++count;
                    reverse(matrixA, i, j);
                }
            }
    
            if (!IsSameMatrix()) count = -1;
    
            System.out.println();
            print(matrixA);
            print(matrixB);
    
            bufferedWriter.write(String.valueOf(count));
    
            bufferedWriter.flush();
            bufferedReader.close();
            bufferedWriter.close();
        }
    }

     

    3 4
    0000
    0010
    0000
    1001
    1011
    1001
    
     1 0 0 1
     1 0 1 1
     1 0 0 1
    
     1 0 0 1
     1 0 1 1
     1 0 0 1
    
    2

     

     이제 소스 코드를 하나하나 살펴보겠다.

     

    public static void setMatrix(int[][] matrix, int n, int m) throws IOException {
        for (int i = 0; i < n; i++) {
            String[] rows = bufferedReader.readLine().split("");
            for (int j = 0; j < m; j++) {
                matrix[i][j] = Integer.parseInt(rows[j]);
            }
        }
    }
    

     

     인자로 들어온 n x m 크기의 행렬의 값을 채우는 메소드이다.

     

    public static void reverse(int[][] matrix, int row, int col) {
        for (int i = row; i < row + 3; i++) {
            for (int j = col; j < col + 3; j++) {
                if (matrix[i][j] == 1) {
                    matrix[i][j] = 0;
                } else if (matrix[i][j] == 0) {
                    matrix[i][j] = 1;
                }
            }
        }
    }

     

     시작하는 row와 col 좌표 부터 3개의 좌표를 뒤집는다. 문제에서 3 x 3 부분 행렬로 정해주었기 때문에 상수 3으로 작성하였다.

     

    public static boolean IsSameMatrix() {
        for (int i = 0; i < matrixA.length; i++) {
            for (int j = 0; j < matrixA[0].length; j++) {
                if (matrixA[i][j] != matrixB[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

     

     static으로 선언된 행렬 A와 행렬 B의 값이 같은지 확인하는 boolean 메소드이다. 하나라도 틀린 값이 있으면 즉시 false를 반환한다.

     

    public static void print(int[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                System.out.printf("%2d", matrix[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }

     

     디버깅을 위한 print 메소드이다. 정답 제출시에는 필요하지 않다.

     

    public static void main(String[] args) throws IOException {
    
        bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out));
    
        String[] inputSplit = bufferedReader.readLine().split(" ");
        int n = Integer.parseInt(inputSplit[0]);
        int m = Integer.parseInt(inputSplit[1]);
    
        matrixA = new int[n][m];
        matrixB = new int[n][m];
    
        setMatrix(matrixA, n, m);
        setMatrix(matrixB, n, m);
    
        int count = 0;
        for (int i = 0; i <= n - 3; i++) {
            for (int j = 0; j <= m -3; j++) {
                if (matrixA[i][j] == matrixB[i][j]) continue;
                ++count;
                reverse(matrixA, i, j);
            }
        }
    
        if (!IsSameMatrix()) count = -1;
    
        System.out.println();
        print(matrixA);
        print(matrixB);
    
        bufferedWriter.write(String.valueOf(count));
    
        bufferedWriter.flush();
        bufferedReader.close();
        bufferedWriter.close();
    }

     

     main 메소드이다. 3 x 3 행렬로 뒤집을 수 있는 index는 한정되어 있기 때문에 0 ~ n - 3, 0 ~ m - 3으로 설정하였다. 각각의 값을 비교하고 같다면 통과한다. 만약 다른 값이라면 count를 증가시키고 뒤집기를 진행한다. 만약 끝까지 진행했지만 두 행렬이 다르다면 count를 -1로 설정하고 값을 출력한다.

    댓글

Designed by Tistory.