문제 링크

알고리즘 문제 중 구현, 시뮬레이션 문제류를 풀 때 기능 분리에만 목적을 두지 말고 좀 더 쉬운 로직을 찾기 위해 노력해야함.

main.cpp 주요 함수들 : 상어먹기, 방향전환, 상어 움직이기, 시뮬레이션 실행 하지만 과도한? 기능 분리 + 세부 연산 실패로 문제 푸는 데 오래걸림

내가 생각한 연산방법

  • moveshark

예를 들어 UP은 row에서 spd만큼 올라가야 한다. spd가 row보다 작은경우를 제외하고, row가 spd보다 작거나 같은 경우 행렬의 범위를 벗어나게 된다. 더 나아가 spd와 row의 뺀값의 범위에 따라 방향이 바뀌거나 원래 방향으로 돌아오게 된다. 방향이 바뀌는 경우는 rest_spd(뺀 나머지 속도)가 R(전체 행 길이) - 1이하인 경우 방향이 바뀌고 초과한 경우 방향이 원래로 돌아오게 된다. 이 사실을 이용하여 계산하여 함수를 작성하였으나 너무 조잡하고 길다고 느껴져 moveshark2를 구현하게 되었다.

  • moveshark2

위와 같이 구현하면 속도는 더 빠를지 언정 출제자의 목적에 부합하는 풀이였는지 애매모호하여 moveshark2를 작성하게 되었다. moveshark2는 솔직히 잘 짠 코드라고 보기 어렵다. if문에 따라 나누기 보다 차라리 switch로 UP, DOWN, LEFT, RIGHT에 따라 초기화를 개별적으로 해줬으면 좋았을 것 같다. movedistance로 while문을 돌린것은 괜찮은 아이디어였던것 같다. 부가적으로 spd가 0인 경우도 좀 더 깔끔하게 처리할 수 있을것 같다.

  • 다른사람 풀이

moveshark2 와 핵심 로직은 비슷하다. 배울점으로는 struct를 이용하여 shark를 정의하여 좀 더 가독성 높은 코드를 작성하였다는 점이 있다.

상어의 잡기와 이동을 for문에 전부 넣을 수 있다는 아이디어를 생각하지 못한것이 아쉬웠다.

내 코드

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>

const int UP = 1;
const int DOWN = 2;
const int RIGHT = 3;
const int LEFT = 4;

using namespace std;

struct shark
{
    int r, c, s, d, z;
    shark(int _r, int _c, int _s, int _d, int _z) : r(_r), c(_c), s(_s), d(_d), z(_z){}
};

int mat[101][101];
int R, C, M;
vector<shark> slist;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> R >> C >> M;
    int r, c, s, d, z, ret = 0;
    while (M--)
    {
        cin >> r >> c >> s >> d >> z;
        if (d == UP || d == DOWN)
            s %= 2 * (R - 1);
        else
            s %= 2 * (C - 1);
        mat[r][c] = z;
        slist.push_back(shark( r, c, s, d, z ));
    }

    for (int t = 1; t <= C; t++)
    {
        for (int row = 1; row <= R; row++)
        {
            if (mat[row][t])
            {
                ret += mat[row][t];
                mat[row][t] = 0;
                break;
            }
        }

        vector<shark> new_slist;
        for (shark s : slist)
        {
            if (mat[s.r][s.c] != s.z)
                continue;
            int spd = s.s;
            while (spd)
            {
                switch (s.d)
                {
                case UP:
                    s.r -= spd;
                    if (s.r <= 0) {
                        spd = 1 - s.r;
                        s.r = 1;
                        s.d = DOWN;
                    }
                    else
                        spd = 0;
                    break;
                case DOWN:
                    s.r += spd;
                    if (s.r > R) {
                        spd = s.r - R;
                        s.r = R;
                        s.d = UP;
                    }
                    else
                        spd = 0;
                    break;
                case RIGHT:
                    s.c += spd;
                    if (s.c > C) {
                        spd = s.c - C;
                        s.c = C;
                        s.d = LEFT;
                    }
                    else
                        spd = 0;
                    break;
                case LEFT:
                    s.c -= spd;
                    if (s.c <= 0) {
                        spd = 1 - s.c;
                        s.c = 1;
                        s.d = RIGHT;
                    }
                    else
                        spd = 0;
                    break;
                }
            }
            new_slist.push_back(s);
        }

        slist.swap(new_slist);

        for (int row = 1; row <= R; row++) for (int col = 1; col <= C; col++)
        {
            mat[row][col] = 0;
        }

        for (shark s : slist)
        {
            if (mat[s.r][s.c] < s.z)
                mat[s.r][s.c] = s.z;
        }
    }

    cout << ret << "\n";
}

댓글남기기