[ 백준 ] 17140 / 이차원 배열과 연산

金弘均·2021년 9월 15일
0

Baekjoon Online Judge

목록 보기
29/228
post-thumbnail
post-custom-banner

# Appreciation

/*
 * Problem :: 17140 / 이차원 배열과 연산
 *
 * Kind :: Simulation
 *
 * Insight
 * - 톱니배열인가 싶었는데 아니다
 *   R 연산에서도 가장 큰 행을 기준으로 모든 행의 크기고 변하고
 *   C 연산에서도 가장 큰 열을 기준으로 모든 열의 크기가 변한다
 *   크기가 커진 곳에는 0 이 채워지고 이 0 은 연산시 무시된다
 *   + 오히려 위처럼 정의해줬기 때문에 톱니배열로 생각하지 않고
 *     처음부터 행과 열의 크기가 100인 배열을 생각해서 풀 수 있었다
 *     # 어차피 톱니배열이라해도 행 연산과 열 연산이 구분되어 있으니
 *       배열을 (vector<vector<int>>) A로 생각한다면
 *       A[i] 로 행 연산은 쉽게 구현될지 모르나
 *       열 연산의 경우 기존 공간을 뒤집어주거나 하나씩 세어서
 *       정렬할  vector<int> 를 새로 만들어주어야 한다
 *       -> 그냥 (int) A[100+1][100+1] 해주는게 정신건강에 좋다
 *
 * - 행별로 또는 열별로 0 이 아닌 숫자들을 추출해서 vector<int> 를 만들고
 *   이를 정렬해서 다시 넣어주는 식으로 처음엔 생각했는데
 *   솔직히 귀찮았다
 *   + Map 써서 수의 등장 횟수를 세고
 *     Vector 써서 수의 등장 횟수가 커지는 순으로, 수가 커지는 순으로 정렬한 후
 *     이를 이용해서 바로 배열을 갱신하는 것이 낫다고 생각했다
 *     # 솔직히 함수 만들기 귀찮았다
 *
 * Point
 * - 힌트가 너무 친절하다
 *
 * - 행 또는 열 연산시 정렬된 결과를 배열에 갱신해줄 때
 *   그 행과 열을 0 으로 초기화 해주어야 한다
 *   + [3, 3, 3] 과 같은 경우 정렬된 결과가 [3, 3] 이 되는데
 *     그 행 또는 열을 0 으로 초기화 하지 않으면
 *     그대로 [3, 3, 3] 으로 남아있게 된다
 */

# Code

//
//  BOJ
//  ver.C++
//
//  Created by GGlifer
//
//  Open Source

#include <iostream>
#include <vector>
#include <map>

using namespace std;

#define endl '\n'

// Set up : Global Variables
int r, c, k;
int A[100+1][100+1];
int cr, cc;

// Set up : Functions Declaration
void op_R();
void op_C();


int main()
{
    // Set up : I/O
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    // Set up : Input
    cin >> r >> c >> k;
    for (int i=1; i<=3; i++)
        for (int j=1; j<=3; j++)
            cin >> A[i][j];

    // Process
    cr = cc = 3; /* 현재 행의 크기, 현재 열의 크기 */
    int time = 0;
    while (A[r][c] != k && time <= 100) {
        time++;
        (cr >= cc) ? op_R() : op_C();

    }

    // Control : Output
    cout << ((time > 100) ? -1 : time) << endl;
}

// Helper Functions
void op_R()
/* R 연산 */
{

    for (int i=1; i<=cr; i++) {
        map<int,int> M; /* 수의 등장 횟수 세기 */
        for (int j=1; j<=cc; j++) {
            if (A[i][j] == 0) continue;
            M[A[i][j]]++;
        }

        vector<pair<int,int>> V(M.begin(), M.end()); /* Map -> Vector */
        sort(V.begin(), V.end(), [](auto &u, auto &v){ /* Sorting */
            return make_pair(u.second, u.first) < make_pair(v.second, v.first);
        });

        int s = V.size();

        for (int j=1; j<=cc; j++) { A[i][j] = 0; } /* 해당 행을 0 으로 초기화 */
        for (int j=0; j<s && 2*j+2<=100; j++) { /* 배열 갱신 */
            A[i][2*j+1] = V[j].first;
            A[i][2*j+2] = V[j].second;
        }

        cc = min(100, max(cc, 2*s)); /* 행의 크기 갱신 */
    }
}

void op_C()
/* C 연산 */
{
    for (int j=1; j<=cc; j++) {
        map<int,int> M; /* 수의 등장 횟수 세기 */
        for (int i=1; i<=cr; i++) {
            if (A[i][j] == 0) continue;
            M[A[i][j]]++;
        }

        vector<pair<int,int>> V(M.begin(), M.end()); /* Map -> Vector */
        sort(V.begin(), V.end(), [](auto &u, auto &v){ /* Sorting */
            return make_pair(u.second, u.first) < make_pair(v.second, v.first);
        });

        int s = V.size();

        for (int i=1; i<=cr; i++) { A[i][j] = 0; } /* 해당 열을 0 으로 초기화 */
        for (int i=0; i<s && 2*i+2<=100; i++) { /* 배열 갱신 */
            A[2*i+1][j] = V[i].first;
            A[2*i+2][j] = V[i].second;
        }

        cr = min(100, max(cr, 2*s)); /* 열의 크기 갱신 */
    }
}
profile
이런 미친 게임을 봤나! - 옥냥이
post-custom-banner

0개의 댓글