본문 바로가기

Coding Test

백준 1455 뒤집기 2

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

 

#include <iostream>
#include <vector>

using namespace std;

vector<vector<int>> arr;

int main() {

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);


    int n, m;
    int ans = 0;

    cin >> n >> m;

    arr.resize(n, vector<int>(m));

    for (int i = 0; i < n; i++) {
        string temp;
        cin >> temp;

        for (int j = 0; j < m; j++) {
            arr[i][j] = temp[j] - '0';
        }
    }

    for (int i = n - 1; i >= 0; i--) {
        for (int j = m - 1; j >= 0; j--) {
            if (arr[i][j] == 1) {
                ans++;
                for (int k = 0; k <= i; k++) {
                    for (int l = 0; l <= j; l++) {
                        arr[k][l] = 1 - arr[k][l];
                    }
                }

            }
        }
    }

    cout << ans;


    return 0;
}

1. 문제

n*m으로 이루어진 동전의 배열이 앞면은 0, 뒷면은 1로 주어진다. (a, b) 위치의 동전을 뒤집으면 (0~a, 0~b)에 해당하는 모든 동전이 뒤집어지고, 이를 연산 한 번으로 간주한다. 이 때, 모든 동전을 앞면으로 바꾸기 위한 최소 횟수를 구하라.

2. 풀이

가장 많이 동전을 뒤집을 수 있는 우측 최하단부터 그리디하게 체크한다. 동전이 뒷면일 경우 연산을 수행해나간다.

for (int i = n - 1; i >= 0; i--) {
        for (int j = m - 1; j >= 0; j--) {
            if (arr[i][j] == 1) {
                ans++;
                for (int k = 0; k <= i; k++) {
                    for (int l = 0; l <= j; l++) {
                        arr[k][l] = 1 - arr[k][l];
                    }
                }

            }
        }
    }

동전이 뒷면일 경우 문제에서 정의된 대로 좌측 최상단부터 현재 위치까지의 모든 동전을 뒤집는다. 한번 연산을 했을 때 연산 범위 내의 동전이 앞면이 되면 그 동전은 그대로 둬도 되고, 뒷면이 되면 어짜피 뒤집어야 하므로 연산의 횟수를 계산해서 늘려야 한다. 

 위 연산 후 ans를 출력하면 정답을 구할 수 있다.

'Coding Test' 카테고리의 다른 글

백준 1474 밑 줄  (1) 2024.07.09
백준 17615 볼 모으기  (0) 2024.07.08
백준 14400 편의점 2  (0) 2024.07.06
백준 14247 나무 자르기  (0) 2024.07.06
백준 1946 신입 사원  (0) 2024.07.04