코딩/백준

[백준]3190번 뱀 - C++

최선을 다하는 2023. 1. 11. 19:24

https://www.acmicpc.net/problem/3190

 

3190번: 뱀

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

www.acmicpc.net


구현 문제이다. 게임의 흐름에 따라 분기 처리를 한다면 쉽게 풀 수 있다.

1. 방향에 따라 이동할 칸을 정한다.

2. 이동할 칸이 "뱀 (1)" 이거나 "벽(-1)" 이면 게임 종료.

    이동할 칸이 "빈칸(0)" 이거나 "사과(2)" 이면 그대로 진행.

        - 어디든 이동할 칸은 뱀(1)으로 교체

        - 빈칸이라면 꼬리(1)를 빈칸(0)으로, 사과(2)라면 꼬리(1) 유지

3. 이동이 끝난 후 방향 전환 시간이 된다면 방향 전환.

#include <iostream>
#include <vector>
#include <deque>
#include <queue>
using namespace std;

typedef pair<int,char> pic;
int mat[110][110] = {0};

priority_queue < pic, vector<pic> , greater<pic> >  dinfo;
deque<pair<int,int> > dq;
int dir;
int dx[4] = {0,1,0,-1};
int dy[4] = {1,0,-1,0};
int N, K, L;
int a, b, ret = 0;
char c;

void changeDir(char d){
    if(d == 'D')
        dir = (dir + 1) % 4;
    else if(d == 'L'){
        dir -= 1;
        if(dir == -1)
            dir += 4;
    }
}

bool valid(int x, int y){
    if( mat[x][y] == 1 || mat[x][y] == -1)
        return false;
    return true;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    cin >> N;
    for(int i = 0 ; i <= N + 1;i++){
        mat[i][0] = -1;
        mat[0][i] = -1;
        mat[i][N + 1] = -1;
        mat[N + 1][i] = -1;
    }
    cin >> K;
    for(int i = 0 ; i < K ;i++){
        cin >> a >> b;
        mat[a][b] = 2;
    }
    cin >> L;
    for(int i = 0 ; i < L ;i++){
        cin >> a >> c;
        dinfo.push(make_pair(a,c));
    }
    
    dir = 0;
    dq.push_front(make_pair(1,1));
    while(1){
        ret++;
        int curx = dq.front().first + dx[dir];
        int cury = dq.front().second + dy[dir];
        if(valid(curx,cury)){
            dq.push_front(make_pair(curx,cury));
            if(mat[curx][cury] != 2){
                mat[dq.back().first][dq.back().second] = 0;
                dq.pop_back();
            }
            mat[curx][cury] = 1;
            if(!dinfo.empty() && ret == dinfo.top().first){
                changeDir(dinfo.top().second);
                dinfo.pop();
            }
        }
        else{
            break;
        }
    }
    cout << ret;
}

미리 연습장에 게임의 흐름을 다 구현해놓았더니 예제 두 개를 풀 수 있었다. 나머지 한 예제는 시간 별로 게임판을 출력한 결과 방향 전환이 왼쪽으로 잘 안되었고 보니 dir -= dir로 되어있어 1을 감소하도록 바꿔주었더니 모든 예제가 잘 되었고 제출을 하니 다 맞을 수 있었다. 구현 문제가 설계를 잘하고 들어가서 한 번에 되면 쾌감이 엄청난 것 같다!!

'코딩 > 백준' 카테고리의 다른 글

[백준]1717번 집합의표현 - C++  (0) 2023.01.13
[백준] 14890번 경사로 - C++  (0) 2023.01.12
[백준]2589번 보물섬 - C++  (0) 2023.01.06
[백준]3055번 탈출 - C++  (0) 2023.01.04
[백준]11657 타임머신 - C++  (0) 2023.01.03