[HackerRank #01] Forming a Magic Square

이석환·2023년 4월 10일
0

HackerRank

목록 보기
2/2

문제 정리
1. 3 X 3 행렬을 입력 받는다.
2. 주어진 행렬의 가로, 세로, 대각선의 합이 동일한 값이 나오도록 행렬의 값을 바꾼다.
3. 바꾼 행렬의 값과 기존의 행렬값을 비교하여 차이값을 더하여 출력


출처 : https://www.hackerrank.com/challenges/magic-square-forming/problem?isFullScreen=true

문제 해결 전략
1. 3 X 3 행렬의 Magic Square (마방진)은 합이 15이며 경우의 수가 8개밖에 존재하지 않는다.

2. 마방진이 되는 경우의 수 8개의 행렬을 모두 저장해둔 뒤 입력받은 행렬과 비교하며 모든 경우의 수와의 차이값을 구하자 !

3. 각 경우의 수와의 차이를 계속해서 MIN_VAL에 MIN() 함수를 이용하여 갱신해주면 최솟값을 찾을 수 있다.

#include <iostream>
#include <algorithm>

using namespace std;

struct pos {
    int a, b, c;
};
int MIN_VAL = 987654321;
int arr[3][3];

pos mat[8][3] = {
        {{6, 7, 2}, {1, 5, 9}, {8, 3, 4}},
        {{4, 9, 2}, {3, 5, 7}, {8, 1, 6}},
        {{8, 1, 6}, {3, 5, 7}, {4, 9, 2}},
        {{6, 1, 8}, {7, 5, 3}, {2, 9, 4}},
        {{2, 9, 4}, {7, 5, 3}, {6, 1, 8}},
        {{8, 3, 4}, {1, 5, 9}, {6, 7, 2}},
        {{4, 3, 8}, {9, 5, 1}, {2, 7, 6}},
        {{2, 7, 6}, {9, 5, 1}, {4, 3, 8}}
};

void solve() {
    for (int i = 0; i < 8; i++) {
        int diff = 0;
        for (int j = 0; j < 3; j++) {
            int a = mat[i][j].a;
            int b = mat[i][j].b;
            int c = mat[i][j].c;

            int x = arr[j][0];
            int y = arr[j][1];
            int z = arr[j][2];
            diff += abs(a - x) + abs(b - y) + abs(c - z);
        }
        MIN_VAL = min(MIN_VAL, diff);
    }

    cout << MIN_VAL;
}

void Init() {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cin >> arr[i][j];
        }
    }
}

int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    Init();
    solve();
    return 0;
}

본인은 기존 마방진을 저장할 때 직관성을 주기 위해 pos구조체를 정의하였다.
하지만 3차원 배열을 사용하여 코딩하면 오히려 solve() 함수에서의 반복문 부분에서 가독성이나 구현이 훨씬 깔끔했을 거 같다는 생각이 들긴 한다.

소감
처음 코딩할 때는 주어진 행렬을 마방진으로 바꾸는 코드를 작성하였다. 코딩 도중에 코드 수가 너무 길어지고 직관성이 너무 떨어져 다른 방법을 찾고자 Discussions에 고수들의 코드를 봤다.
마방진을 저장해두고 비교하는 게 훨씬 빠르고 쉽구나 .. 많은 게 부족하다고 느끼게 된 문제였다.
하지만 4 X 4 이상의 마방진부터는 저장해두고 사용하는 게 안 되기 때문에 다른 방법으로도 코딩을 다시 해봐야겠다는 생각이 들었다.
단순히 3 X 3 마방진이기 때문에 가능했던 방법이였다.
나중에 기존에 했던 DFS를 통한 재귀로 구현하는 방법으로 다시 코딩해봐야겠다.
첫 번째 Medium 문제였는데 생각보다 너무 쉽다는 생각이 들었다.

profile
반갑습니다.

0개의 댓글