Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

코린이 탈출기

[모의 SW 역량테스트][C++] 핀볼 게임 본문

문제 풀이/Simulation

[모의 SW 역량테스트][C++] 핀볼 게임

명란파스타 2020. 9. 18. 22:45

문제 바로가기

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

<문제 풀이 Logic>

- info[][] 배열: 각 블럭에 부딪혔을 때 기존의 방향이 어떻게 달라지는 지를 저장하고 있음(key: 기존 방향, value: 새로운 방향 / 0: →, 1: ↓, 2: ←, 3: ↑)

- warmHole 벡터: 각 warm hole의 (y, x) 쌍을 저장한다

 

1. 주어진 map의 바깥에 블럭 5를 한줄씩 더 만든다. (5의 모양이 ㅁ이므로 제일 가장자리를 만났을 때 방향을 꺾도록 하기 위해서)

2. map[y][x]가 0인 부분에서 네 가지 방향으로 모두 simulate 한다.

in Simulate()

1. 현재 가진 방향으로 옮겨서 ny, nx를 구한다.

2. 그 자리에 블럭이 있다면(isBlock()) score을 올리고, 방향을 info 배열에 맞게 갱신한다

3. 그 자리에 warmHole이 있다면(isWarmHole()) findPair() 함수를 호출하여 반대편 웜홀로 y, x 값을 갱신한다.

4. 이를 블랙홀을 만날 때까지, 혹은 시작점을 만날 때까지 반복한다.

while (map[y][x] != -1 && !((y == start_y) && (x == start_x)))

 

 

-전체 코드-

#include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>

using namespace std;

int pos[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int map[102][102];
int info[5][4] = { {2,0,3,1},{2,3,1,0},{1,3,0,2},{3,2,0,1},{2,3,0,1} };
vector<pair<int, int>> warmHole[5];

bool isBlock(int y, int x)
{
    if (map[y][x] >= 1 && map[y][x] <= 5)
        return true;
    return false;
}

bool isWarmHole(int y, int x)
{
    if (map[y][x] >= 6 && map[y][x] <= 10)
        return true;
    return false;
}

pair<int, int> findPair(int y, int x, int num)
{
    for (int i = 0; i < 2; i++)
    {
        if (warmHole[num][i] != make_pair(y, x))
            return warmHole[num][i];
    }

    return make_pair(-1, -1);
}

int simulate(int y, int x, int dir)
{
    int start_y = y;
    int start_x = x;
    int score = 0;

    do
    {
        y += pos[dir][0];
        x += pos[dir][1];

        if (isBlock(y, x))
        {
            int blocknum = map[y][x] - 1;
            score++;
            dir = info[blocknum][dir];
        }

        if (isWarmHole(y, x))
        {
            int warmHoleNum = map[y][x]-6;
            pair<int, int> holePair = findPair(y, x, warmHoleNum);
            y = holePair.first;
            x = holePair.second;
        }
    } while (map[y][x] != -1 && !((y == start_y) && (x == start_x)));

    return score;
}

int main()
{
    int test_case;
    int T, N;

    cin >> T;

    for (test_case = 1; test_case <= T; ++test_case)
    {
        memset(map, 0, sizeof(map));

        for (int i = 0; i < 5; i++)
        {
            warmHole[i].clear();
        }

        cin >> N;
        for (int i = 0; i <= N + 1; i++)
        {
            map[i][0] = 5;
            map[i][N + 1] = 5;
            map[0][i] = 5;
            map[N + 1][i] = 5;
        }

        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
            {
                cin >> map[i][j];
                if (map[i][j] >= 6 && map[i][j] <= 10)
                {
                    warmHole[map[i][j] - 6].push_back({ i, j });
                }
            }
        }

        int max_score = 0;
        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
            {
                if (map[i][j] == 0)
                {
                    for (int k = 0; k < 4; k++)
                    {
                        max_score = max(max_score, simulate(i, j, k));
                    }
                }
            }
        }
        cout << "#" << test_case << " " << max_score << endl;
    }


    return 0;//정상종료시 반드시 0을 리턴해야합니다.
}