[삼성 SW 역량평가] 싸움땅(C++)

Alice·2023년 9월 6일
0

풀이 소요시간 : 약 2시간

꽤나 복잡한 시뮬레이션 문제였다. 이 문제를 풀면서 함수화의 중요성을 더욱 크게 느낄 수 있었다. 방향전환, 총의 교체, 이동 가능성 체크 등의 함수화가 정말 중요한 문제였고, 이정도 수준의 시뮬레이션 문제는 함수화를 하지 않을 경우 디버깅해서 오류를 찾아낼 수 조차 없다.


구조체에 최대한 많은 공통사항을 저장하자.

struct Player {
    int x;
    int y;
    int d;
    int s;
    int gun;
    int point;
};
vector<Player> Vector;

위와 같이 현재 들고있는 총, 현재 플레이어의 포인트 등의 공통 사항을 저장하며 풀이했다.


웬만하면 복잡한 시뮬레이션 문제는 함수화를 습관화하자.

bool Check_Move_180(int nx, int ny, int dir) {
    if(nx < 1 || ny < 1 || nx > N || ny > N) return false;
    return true;
}

bool Check_Move_90(int num, int nx, int ny, int dir) {
    if(nx < 1 || ny < 1 || nx > N || ny > N) return false;
    for(int i = 0; i < Vector.size(); i++)
    {
        if(i == num) continue;
        if(Vector[i].x == nx && Vector[i].y == ny) return false;
    }
    return true;
}

위와같은 함수화로 main() 함수의 반복문 코드 수를 줄일 수 있었다.


전체 코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int N, M, K;
vector<int> Map[21][21];

int dx[4] = {-1 ,0, 1, 0};
int dy[4] = {0, 1, 0, -1};
//상 우 하 좌

struct Player {
    int x;
    int y;
    int d;
    int s;
    int gun;
    int point;
};
vector<Player> Vector;

void Input() {
    cin >> N >> M >> K;

    //총 정보 
    for(int i = 1; i <= N; i++)
    {
        for(int j = 1; j <= N; j++)
        {
            int gun;
            cin >> gun;
            Map[i][j].push_back(gun);
        }
    }

    //플레이어 정보
    for(int i = 1; i <= M; i++)
    {
        int x, y, d, s;
        cin >> x >> y >> d >> s;
        Vector.push_back({x, y, d, s, 0, 0});
    }
}

int Change_180(int dir) {
    if(dir == 0) return 2;
    if(dir == 1) return 3;
    if(dir == 2) return 0;
    if(dir == 3) return 1;
}

int Change_90(int dir) {
    if(dir == 0) return 1;
    if(dir == 1) return 2;
    if(dir == 2) return 3;
    if(dir == 3) return 0;
}

bool Check_Move_180(int nx, int ny, int dir) {
    if(nx < 1 || ny < 1 || nx > N || ny > N) return false;
    return true;
}

bool Check_Move_90(int num, int nx, int ny, int dir) {
    if(nx < 1 || ny < 1 || nx > N || ny > N) return false;
    for(int i = 0; i < Vector.size(); i++)
    {
        if(i == num) continue;
        if(Vector[i].x == nx && Vector[i].y == ny) return false;
    }
    return true;
}


pair<int, int> Check_Conflict(int num, int x, int y) {
    for(int i = 0; i < Vector.size(); i++)
    {
        if(i == num) continue;
        if(x == Vector[i].x && y == Vector[i].y)
        {
            int Gap = abs((Vector[num].s + Vector[num].gun) - (Vector[i].s + Vector[i].gun));

            if(Vector[num].s + Vector[num].gun > Vector[i].s + Vector[i].gun) 
            {
                Vector[num].point += Gap;
                return {num, i};
            }
            else if(Vector[num].s + Vector[num].gun < Vector[i].s + Vector[i].gun) 
            {
                Vector[i].point += Gap;
                return {i, num};
            }
            else if(Vector[num].s > Vector[i].s) return {num, i};
            else return {i, num};
        }
    }
    return {-1, -1};
}

//해당 칸에서 총 교체
void Change_Gun(int num, int x, int y) {
    //현재 플레이어가 총을 가진 경우
    if(Vector[num].gun > 0)
    {
        Map[x][y].push_back(Vector[num].gun);
    }

    sort(Map[x][y].rbegin(), Map[x][y].rend());
    Vector[num].gun = Map[x][y][0];
    Map[x][y].erase(Map[x][y].begin());
}


int main() {
    Input();
    while(K--)
    {
        for(int i = 0; i < Vector.size(); i++)
        {
            
            //1-1. 플레이어 이동

            while(Check_Move_180(Vector[i].x + dx[Vector[i].d], Vector[i].y + dy[Vector[i].d], Vector[i].d) == false)
            {
                Vector[i].d = Change_180(Vector[i].d);
            }

            Vector[i].x += dx[Vector[i].d];
            Vector[i].y += dy[Vector[i].d];


            //2. 충돌 확인 및 점수 처리
            pair<int, int> Pair = Check_Conflict(i, Vector[i].x, Vector[i].y);
            int win = Pair.first;
            int lose = Pair.second;

            //2-2-1
            if(win == -1 && lose == -1)
            {
                if(Map[Vector[i].x][Vector[i].y].size() > 0)
                {
                    Change_Gun(i, Vector[i].x, Vector[i].y);
                }
                continue;
            }

            //2-2-2
            if(Vector[lose].gun > 0)
            {
                Map[Vector[lose].x][Vector[lose].y].push_back(Vector[lose].gun);
                Vector[lose].gun = 0;
                sort(Map[Vector[lose].x][Vector[lose].y].rbegin(), Map[Vector[lose].x][Vector[lose].y].rend());
            }

            while(Check_Move_90(lose, Vector[lose].x + dx[Vector[lose].d], Vector[lose].y + dy[Vector[lose].d], Vector[lose].d) == false)
            {
                Vector[lose].d = Change_90(Vector[lose].d);
            }

            Vector[lose].x += dx[Vector[lose].d];
            Vector[lose].y += dy[Vector[lose].d];
            if(Map[Vector[lose].x][Vector[lose].y].size() > 0)
            {
                Change_Gun(lose, Vector[lose].x, Vector[lose].y);
            }

            //2-2-3
            if(Map[Vector[win].x][Vector[win].y].size() > 0)
            {
                Change_Gun(win, Vector[win].x, Vector[win].y);
            }

        }
    }

    for(auto E : Vector)
    {
        cout << E.point << ' ';
    }
    cout << endl;
}
profile
SSAFY 11th

0개의 댓글