본문 바로가기
백준/그리디

백준 1080. 행렬

by 29살아저씨 2021. 8. 18.
반응형

🅰 백준 1080. 행렬

✏️ 문제 풀이

  • 행렬을 변환하는 연산은 3X3 행렬을 뒤집는 것이다. 그러므로 행렬이 3보다 작을 때, 행렬이 3보다 클 때 2가지 경우를 생각하였다.
  • 1. 행렬이 3보다 작을 때
    • 두 행렬이 같으면 0 출력 / drawCnt변수를 이용하여 같으면++ 해주고 drawCnt = N*M이면 같다고 출력
    • 두 행렬이 다르면 -1 출력
  • 2. 행렬이 3보다 클 때
    • 데이터를 입력받을 때 boolean배열을 이용하여 데이터가 두 데이터가 같으면 true, 틀리면 false로 저장을 했다.
    • boolean배열을 탐색하면서 false라면 그 부분부터 시작해서 3*3행렬만큼 true->false, false->true로 변경해주고 cnt를 이용하여 변경한 횟수를 카운트 해주었다.
    • 모든 배열을 변경 완료 후 boolean배열을 탐색을 하여 전부 true이면 카운트 해준 cnt를 출력해주었다.

✏️ 소스코드

package greedy;

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

public class Main_실버2_1080_손은성 {

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		int cnt = 0;
		int drawCnt = 0;
		int arrN[][] = new int[N][M];
		int arrM[][] = new int[N][M];
		boolean arrCheck[][] = new boolean[N][M];

		// N 데이터 입력
		for (int i = 0; i < N; i++) {
			String strN = br.readLine();
			for (int j = 0; j < M; j++) {
				arrN[i][j] = strN.charAt(j) - '0';
			}
		}
		// M 데이터 입력
		for (int i = 0; i < N; i++) {
			String strN = br.readLine();
			for (int j = 0; j < M; j++) {
				arrM[i][j] = strN.charAt(j) - '0';
				if (arrN[i][j] == arrM[i][j]) {
					arrCheck[i][j] = true;
					drawCnt++;
				}
			}
		}
		// 행렬이 3보다 작을 때
		if (N < 3 && M < 3) {
			// 두 행렬이 같으면 0 출력
			if (drawCnt == N * M)
				System.out.println(0);
			// 두 행렬이 다르면 -1 출력
			else
				System.out.println(-1);
		} 
		
		// 행렬이 3보다 클 때
		else {
			for (int i = 0; i <= N - 3; i++) {
				for (int j = 0; j <= M - 3; j++) {
					if (!arrCheck[i][j]) { // check배열이 false라면 (변경해 줘야 한다면)
						for (int i2 = i; i2 < i + 3; i2++) { // check부터 시작해서 3X3만큼 값 변경
							for (int j2 = j; j2 < j + 3; j2++) {
								arrCheck[i2][j2] = arrCheck[i2][j2] == true ? false : true; // 삼항 연산자 이용하여 true->false, false->true로 변경
							}
						}
						cnt++; // 한번 뒤집을 때 마다 count 1씩 증가
					}
				}
			}
			
			// boolean배열 체크
			Loop1: for (int i = 0; i < N; i++) {
				for (int j = 0; j < M; j++) {
					// 하나라도 false가 있으면 -1 출력
					if (!arrCheck[i][j]) {
						System.out.println(-1);
						break Loop1;
					} 
					// 전부 확인 후 true이면 cnt출력
					else if (i == N - 1 && j == M - 1) {
						System.out.println(cnt);
					}
				}
			}
		}
	}
}

 

✅ 후기

  • 마찬가지로 boolean배열을 생성하는것까지 생각을 했으나 좀 더 고민을 못하고 구글을 참고를 해서 풀었다. 9문제 정도를 푸니 그리디에 대해 어느정도 감이 잡히고 논리적인 사고와 수학적 지식도 어느정도는 필요하다는 것을 느꼈다.
반응형

'백준 > 그리디' 카테고리의 다른 글

백준 1783. 병든 나이트  (0) 2021.08.18
백준 2875. 대회 or 인턴  (0) 2021.08.18
백준 1744. 수 묶기  (0) 2021.08.17
백준 1541. 잃어버린 괄호  (0) 2021.08.17
백준 11399. ATM  (0) 2021.08.17

댓글