Dlise
시원한 냉장고
Dlise
전체 방문자
오늘
어제
  • 시원한 냉장고 (136)
    • Java (31)
      • Java (26)
      • Spring (5)
    • Algorithm & PS (25)
      • Algorithm (14)
      • Problem Solving (11)
    • Network (12)
    • Database (2)
    • Data Structure (4)
    • OOP & CleanCode (5)
    • Web (0)
    • Git (2)
    • AI (2)
    • Project (1)
      • Discord Bot (1)
    • Error (19)
    • Tools (5)
    • 수학 (5)
      • 확률과 통계(기초) (5)
    • 컴퓨터 구조 (3)
    • 활동 (20)
      • 행사 & 여행 (10)
      • 자격증 (4)
      • 회고 (6)
      • 기타 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 통계학
  • 후위 표기법
  • 중위 표기법
  • java
  • CleanCode
  • spring security in action second edition
  • 가장쉬운알고리즘책
  • 열혈강의자료구조
  • 백준
  • 네트워크

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Dlise

시원한 냉장고

Algorithm & PS/Problem Solving

백준 - 1080. 행렬

2024. 1. 31. 09:27

앞으로는 정리하면 좋을 것 같다고 생각이 드는 문제에 대해 글을 남길 계획이다.

 

1080. 행렬

 

https://www.acmicpc.net/problem/1080

 

1080번: 행렬

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

www.acmicpc.net

 

입출력

 

설명

행렬의 크기 N, M과 두 행렬 A, B가 주어진다.

A를 B와 동일하게 만들기 위해 3*3 크기의 부분 행렬을 뒤집는 최소 연산 횟수를 출력해야 한다.

만약 동일하게 만들 수 없다면 -1을 출력해야 한다.

 

접근

실버 1 문제라서 무난하겠거니 생각했는데 문제를 아무리 읽어도 방법이 떠오르지 않아서 고생했다.

대부분의 문제들이 그렇듯 눈으로는 정말 쉽게 풀겠는데 막상 코드 작성은 하지 못하는 경우였다.

 

주변에서 그리디 알고리즘(Greedy Algorithm)이라는 힌트를 받고서야 풀 수 있었다.

 

풀이

3*3 크기의 부분 행렬에 있는 모든 원소를 뒤집는다는 점을 활용해야 한다.

이 말의 의미는 아래와 같이 3*3 미만 크기의 행렬만큼 뒤집을 수 없다는 것이다.

따라서 (0,0) 위치의 원소를 뒤집기 위해선 반드시 (1,1)을 중심으로 하는 부분 행렬을 뒤집어야 한다.

 

즉, 중심에서 왼쪽 위의 값이 같으면 뒤집지 않고 다르면 뒤집으면 된다.

 

그 후 A와 B를 비교했을 때 내용이 다르다면 동일하게 만들 수 없다고 판단해 -1을 반환한다.

 

코드

initMap: 행렬을 입력 값에 맞게 초기화한다.

changeMap: 왼쪽 위의 값이 다르면 3*3 만큼을 뒤집는다.

checkMap: 결과를 비교한다.

import java.io.*;
import java.util.StringTokenizer;

public class Main {

    static boolean[][] map;
    static boolean[][] result;
    static int N;
    static int M;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());

        map = initMap(br);
        result = initMap(br);

        int answer = 0;
        for(int i = 1; i < N-1; i++) {
            for(int j = 1; j < M-1; j++) {
                if(map[i-1][j-1] != result[i-1][j-1]) {
                    changeMap(i, j);
                    answer++;
                }
            }
        }

        if(checkMap()) {
            bw.append(String.valueOf(answer));
        } else {
            bw.append("-1");
        }
        bw.flush();
    }

    static boolean[][] initMap(BufferedReader br) throws IOException {
        boolean[][] map = new boolean[N][M];
        for(int i = 0; i < N; i++) {
            String temp = br.readLine();
            for(int j = 0;j < M; j++){
                map[i][j] = temp.charAt(j) - '0' != 0;
            }
        }
        return map;
    }

    static void changeMap(int n, int m) {
        for(int i = n-1; i <= n+1; i++) {
            for(int j = m-1; j <= m+1; j++) {
                map[i][j] = !map[i][j];
            }
        }
    }

    static boolean checkMap() {
        for(int i = 0; i < N; i++) {
            for(int j = 0; j < M; j++) {
                if(map[i][j] != result[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
}

'Algorithm & PS > Problem Solving' 카테고리의 다른 글

백준 - 18405. 경쟁적 전염  (0) 2024.06.19
백준 - 2096. 내려가기  (0) 2024.03.25
백준 - 12865. 평범한 배낭  (1) 2024.01.31
프로그래머스 - 연속된 부분 수열의 합  (0) 2023.06.25
프로그래머스 - 정수를 나선형으로 배치하기  (0) 2023.06.21
    'Algorithm & PS/Problem Solving' 카테고리의 다른 글
    • 백준 - 2096. 내려가기
    • 백준 - 12865. 평범한 배낭
    • 프로그래머스 - 연속된 부분 수열의 합
    • 프로그래머스 - 정수를 나선형으로 배치하기
    Dlise
    Dlise

    티스토리툴바