해보자

백준_17837번_새로운게임2 본문

C++/Solve & Think

백준_17837번_새로운게임2

안댕 2020. 10. 10. 10:55

문제 포인트

  • 색깔별로 어떤 행동을 취하는지?

    • BLUE : 벽과 같은 역할, 방향 변경(변경후에도 문제가 있으면 방향만 변경한 상태로 둠)
      • 벽에 대한 함수를 만들고 BLUE에 대해서도 동일하게 처리하자
    • RED : 뒤집어줌
      • reverse
    • WHITE : 가만히
  • 이동할 타겟의 위에 얹어진 타겟과 함께 이동한다.

    • iterator, find

       

소스코드

#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#define WHITE 0 
#define RED 1
#define BLUE 2

using namespace std;

struct target {
    int y, x;
    int d;
};

int N, K;
int board[13][13];
target targets[11];
vector<int> tv[13][13];

// 제자리, 오, 왼, 위, 아래
int dy[5] = { 0, 0, 0, -1, 1 };
int dx[5] = { 0, 1, -1, 0, 0 };

bool isWallet(int y, int x) {
    if (!(y > 0 && y <= N && x > 0 && x <= N)) return true;
    if (board[y][x] == BLUE) return true;
    return false;
}
bool go() {
    for (int num = 1; num <= K; num++) {
        target cur = targets[num]; // 현재 말 가져오기
        // next point 설정
        int ny = cur.y + dy[cur.d]; 
        int nx = cur.x + dx[cur.d];
        int nd = cur.d;

        // next 검증(보드판 밖이나 파란색(벽)이 있는지 확인)
        if ( isWallet(ny, nx)){
            nd = nd % 2 == 0 ? nd - 1 : nd + 1;
            ny = cur.y + dy[nd];
            nx = cur.x + dx[nd];
            targets[num].d = nd;
            if (isWallet(ny, nx))  
                continue;
        }

        // white, red에 대한 처리
        vector<int>::iterator it = find(tv[cur.y][cur.x].begin(), tv[cur.y][cur.x].end(), num); // index검색
        vector<int> temp(it, tv[cur.y][cur.x].end()); 
        if (tv[cur.y][cur.x].size() == temp.size())
            tv[cur.y][cur.x].clear(); // 전부 다
        else
            tv[cur.y][cur.x] = vector<int>(tv[cur.y][cur.x].begin(), it); // 앞부분만 남겨놓고

        if (board[ny][nx] == RED) {
                // 뒤집고
                reverse(temp.begin(), temp.end());
        }

        //합치기
        for (int i = 0; i < temp.size(); i++) {
            tv[ny][nx].push_back(temp[i]);
            targets[temp[i]].y = ny;
            targets[temp[i]].x = nx;
        }
        if ( tv[ny][nx].size() >= 4) // 4개 이상의 말이 얹어지면?
            return true;
    }
    return false;
}

int main() {
    cin >> N >> K;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> board[i][j]; // 0은 흰색, 1은 빨간색, 2는 파란색
        }
    }
    int y, x, d;
    for (int i = 1; i <= K; i++) {
        cin >> y >> x >> d;
        targets[i] = { y,x,d }; // y, x, 좌표
        tv[y][x].push_back(i); //target의 index
    }

    int turn = 1;
    while (1) {
        if (turn > 1000) { // 1000번 이상 -> 게임 종료
            cout << "-1";
            return 0;
        }
        if (go()) {
            break;
        }
        turn++;
    }
    cout << turn;
    return 0;
}

'C++ > Solve & Think' 카테고리의 다른 글

백준_14499_주사위굴리기  (0) 2020.11.24
백준_5373번_큐빙  (0) 2020.11.24
백준_16236번_아기상어  (0) 2020.10.09
백준_16234번_인구 이동  (0) 2020.10.08
백준_15686번_치킨 배달  (0) 2020.10.08