20-08-19

1. 방향에 따라 x, y값을 어떻게 변화시킬지에 대한 방법을 생각해내지 못함

2. 뱀의 꼬리에 대한 값을 너무 안일하게 생각함(while문 전의 y, x가 꼬리라고 생각함, 길이 생각 못함)

 

https://2youngjae.tistory.com/112

 


20-08-31

[문제보기]

 3190. 뱀

 

3190번: 뱀

 'Dummy' 라는 도스게임이 있다. 이 게임에는 뱀이 나와서 기어다니는데, 사과를 먹으면 뱀 길이가 늘어난다. 뱀이 이리저리 기어다니다가 벽 또는 자기자신의 몸과 부딪히면 게임이 끝난다. 게임

www.acmicpc.net

 

[풀이과정]

이 문제는 시뮬레이션 문제로 조건에 맞춰 뱀만 잘 움직여주면 되는 문제이다. 하지만 처음에는 위에 말했던 2가지 

이유로 풀지를 못해 블로그를 참고를 했던 문제이고, 2주정도가 흐른 지금 다시 풀어본 문제이다.

 

필자는 vector를 사용하여 문제를 풀었는데, vector형태로 info, snake 변수 두개를 만들어 info에는 입력값으로 

주어지는 {시간, 방향}에 대한 값을 저장해주고, snake는 while()문 연산을 통해 뱀이 존재하고 있는 곳을 저장할 

예정이다. 그리고 map 2차원 배열을 사용하여 1은 사과, 2는 뱀이 있는 곳으로 전처리해준다.

 

while()을 통해 뱀의 움직임에 대한 연산을 진행한다. 

pair<int, int> movdir의 인덱스를 통해 'D', 'L'에 대한 움직임을 구현해주는데, 이를 위해 movdir에 상,좌,하,우 순서로 

저장해두었다. 그리고 direction()함수를 통해 movdir 인덱스의 사이클을 만들어 주었다.

이를 통해 방향에 대한 값을 받아와 nexty, nextx값을 만들어준다. nexty, nextx값이 벽에 부딪힌 경우 break를 해주고,

뱀의 꼬리가 존재하는 경우도 break를 해주어 while()문을 중단시켜준다.

 

저 두 경우가 아니면 뱀이 계속 움직일 수 있는 경우인데 이 부분에서 사과를 먹을 경우, 못 먹을 경우에 대해 

조건문을 통해 나눠준다. 조심해줘야되는 경우는 사과를 못 먹을 경우 뱀의 맨 끝 부분이 없어지는 부분이다. 

필자는 이 부분을 vector snake에 뱀이 존재하는 경우를 넣어주면서 사과를 못 먹을 경우, snake.begin()을 없애는 

것으로 구현을 해주었다.

 

[소스코드]

#include <iostream>
#include <vector>
using namespace std;
int map[101][101] = {0};
vector<pair<int, char>> info;
vector<pair<int, int>> snake;
int n, k, l;
pair<int, int> movdir[4] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
int d = 3;

void direction(char c){
    if(c == 'D'){
        d = d - 1 < 0 ? 3 : d - 1;
    }
    else{
        d = d + 1 > 3 ? 0 : d + 1;
    }
}

int main(){
    cin >> n >> k;

    map[1][1] = 2;
    for(int i=0; i<k; i++){
        int y, x;
        cin >> y >> x;
        map[y][x] = 1;
    }

    cin >> l;
    for(int i=0; i<l; i++){
        int t;
        char c;
        cin >> t >> c;
        info.push_back({t, c});
    }

    snake.push_back({1, 1});
    int time = 0;

    while(1){
        if(!info.empty()){
            if(info.front().first == time){
                direction(info.front().second);
                info.erase(info.begin());
            }
        }
        time++;

        int nexty = snake[snake.size()-1].first + movdir[d].first;
        int nextx = snake[snake.size()-1].second + movdir[d].second;

        if(nexty <= 0 || n < nexty || nextx <= 0 || n < nextx) break;
        if(map[nexty][nextx] == 2) break;

        if(map[nexty][nextx] == 1){
            snake.push_back({nexty, nextx});
        }
        else{
            map[snake[0].first][snake[0].second] = 0;
            snake.push_back({nexty, nextx});
            snake.erase(snake.begin());
        }
        
        map[nexty][nextx] = 2;
    }

    cout << time;
}

 

[해결 과정 중 실수한 부분]

맨 처음 time을 출력했을 때 1 적게 나와서 뭐지 싶었는데, time을 while()문의 맨 마지막부분에 넣어주어서,

1 적게 나왔었다.