[코드트리] 싸움땅

rhkr9080·2023년 9월 2일
0

코드트리

목록 보기
16/29

문제링크 : https://www.codetree.ai/training-field/frequent-problems/problems/battle-ground/description?page=3&pageSize=20

💻 문제 풀이 : C++

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>

#define MAP_SIZE 25
#define MAN_SIZE 35

using namespace std;


struct Player {
	int row;
	int col;
	int dir;
	int stat;
	int gun;
	int point;
};

struct GunMan {
	priority_queue<int> gun;
	int man[MAN_SIZE];
};

int N, M, K;
GunMan MAP[MAP_SIZE][MAP_SIZE];

// ↑, →, ↓, ←
int dr[] = { -1, 0, 1, 0 };
int dc[] = { 0, 1, 0, -1 };

vector<Player> player;

void turnBack(int &dir)
{
	if (dir == 0)
		dir = 2;
	else if (dir == 1)
		dir = 3;
	else if (dir == 2)
		dir = 0;
	else if (dir == 3)
		dir = 1;
}

void turnRight(int &dir)
{
	if (dir == 0)
		dir = 1;
	else if (dir == 1)
		dir = 2;
	else if (dir == 2)
		dir = 3;
	else if (dir == 3)
		dir = 0;
}

int isCrash(int row, int col, int dir)
{
	// 충돌
	if ((row == 1 && dir == 0) ||
		(row == N && dir == 2) ||
		(col == 1 && dir == 3) ||
		(col == N && dir == 1))
	{
		return 1;
	}
	else
		return 0;
}

int isPeople(int r, int c, int idx)
{
	//r = player[idx].row;
	//c = player[idx].col;
	for (int i = 1; i <= M; i++)
	{
		if (i != idx && MAP[r][c].man[i] != 0)
		{
			return i;
		}
	}
	return 0;
}

void move(int s)
{
	MAP[player[s].row][player[s].col].man[s] = 0;
	// 격자 밖으로 나가면
	if (isCrash(player[s].row, player[s].col, player[s].dir)) {
		turnBack(player[s].dir);
		player[s].row += dr[player[s].dir];
		player[s].col += dc[player[s].dir];
	}
	// 격자 안
	else {
		player[s].row += dr[player[s].dir];
		player[s].col += dc[player[s].dir];
	}
	MAP[player[s].row][player[s].col].man[s] = player[s].stat;
}

void loserMove(Player &p, int idx)
{
	int nr = p.row;
	int nc = p.col;
	for (int i = 0; i < 4; i++)
	{
		if (isCrash(nr, nc, p.dir) || isPeople(nr + dr[p.dir], nc + dc[p.dir], idx))
		{
			turnRight(p.dir);
		}
		else {
			move(idx);
			nr = player[idx].row;
			nc = player[idx].col;
			// 진 플레이어 총 획득
			if (!MAP[nr][nc].gun.empty())
			{
				if (player[idx].gun < MAP[nr][nc].gun.top())
				{
					MAP[nr][nc].gun.push(player[idx].gun);
					player[idx].gun = MAP[nr][nc].gun.top();
					MAP[nr][nc].gun.pop();
				}
			}
			break;
		}
	}
}

void actTwo()
{
	int debug = 0;
}


void CLEAR()
{

}

void INPUT()
{
	cin >> N >> M >> K;
	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= N; j++)
		{
			int gun;
			cin >> gun;
			if(gun != 0)
				MAP[i][j].gun.push(gun);
		}
	}
	// player index 1부터 시작
	player.push_back({ 0,0,0,0,0,0 });
	for (int i = 1; i <= M; i++)
	{
		int row, col, dir, stat;
		cin >> row >> col >> dir >> stat;
		player.push_back({ row, col, dir, stat, 0, 0 });
		MAP[row][col].man[i] = stat;
	}
}

void SOLVE()
{
	int time = 0;
	while (time < K)
	{
		for (int p = 1; p <= M; p++)
		{
			int r = player[p].row;
			int c = player[p].col;
			MAP[r][c].man[p] = 0;
			// 1. 일단 움직이고
			move(p);
			// 2. 움직였는데 사람이 있으면
			int i = isPeople(player[p].row, player[p].col, p);
			r = player[p].row;
			c = player[p].col;
			if (i != 0)
			{
				int pointA = player[p].gun + player[p].stat;
				int pointB = player[i].gun + player[i].stat;

				if (pointA > pointB)
				{
					// 이긴 플레이어 포인트 획득
					player[p].point += pointA - pointB;
					// 진 플레이어 총 내려놓기
					MAP[r][c].gun.push(player[i].gun);
					player[i].gun = 0;
					// 진 플레이어 이동
					loserMove(player[i], i);
					// 이긴 플레이어 총 획득
					if (player[p].gun < MAP[r][c].gun.top())
					{
						MAP[r][c].gun.push(player[p].gun);
						player[p].gun = MAP[r][c].gun.top();
						MAP[r][c].gun.pop();
					}
				}
				else if (pointA < pointB)
				{
					// 이긴 플레이어 포인트 획득
					player[i].point += pointB - pointA;
					// 진 플레이어 총 내려놓기
					MAP[r][c].gun.push(player[p].gun);
					player[p].gun = 0;
					// 진 플레이어 이동
					loserMove(player[p], p);
					// 이긴 플레이어 총 획득
					if (!MAP[r][c].gun.empty())
					{
						if (player[i].gun < MAP[r][c].gun.top())
						{
							MAP[r][c].gun.push(player[i].gun);
							player[i].gun = MAP[r][c].gun.top();
							MAP[r][c].gun.pop();
						}
					}
				}
				else {
					if (player[p].stat > player[i].stat)
					{
						// 이긴 플레이어 포인트 획득
						player[p].point += pointA - pointB;
						// 진 플레이어 총 내려놓기
						MAP[r][c].gun.push(player[i].gun);
						player[i].gun = 0;
						// 진 플레이어 이동
						loserMove(player[i], i);
						// 이긴 플레이어 총 획득
						if (!MAP[r][c].gun.empty())
						{
							if (player[p].gun < MAP[r][c].gun.top())
							{
								MAP[r][c].gun.push(player[p].gun);
								player[p].gun = MAP[r][c].gun.top();
								MAP[r][c].gun.pop();
							}
						}
					}
					else {
						// 이긴 플레이어 포인트 획득
						player[i].point += pointB - pointA;
						// 진 플레이어 총 내려놓기
						MAP[r][c].gun.push(player[p].gun);
						player[p].gun = 0;
						// 진 플레이어 이동
						loserMove(player[p], p);
						// 이긴 플레이어 총 획득
						if (!MAP[r][c].gun.empty())
						{
							if (player[i].gun < MAP[r][c].gun.top())
							{
								MAP[r][c].gun.push(player[i].gun);
								player[i].gun = MAP[r][c].gun.top();
								MAP[r][c].gun.pop();
							}
						}
					}
				}
			}
			// 사람이 없으면
			else {
				// 총이 있다면
				if(!MAP[r][c].gun.empty()) {
					if (player[p].gun < MAP[r][c].gun.top()) {
						// 총이 더 세면 놓고가기
						if (player[p].gun != 0)
							MAP[r][c].gun.push(player[p].gun);
						player[p].gun = MAP[r][c].gun.top();
						MAP[r][c].gun.pop();
					}
				}
			}
		}
		actTwo();
		time++;
	}

	int answer = 0;
	for (int p = 1; p <= M; p++)
	{
		cout << player[p].point << " ";
	}
	cout << endl;
}


int main()
{
	CLEAR();
	INPUT();
	SOLVE();

	return 0;
}

📌 memo 😊
⭐ 승패 확인이 문제의 curx였다고 생각...!!
=>
1. 승패 요건을 제대로 읽지 않았다
2. 승패 판단을 함수로 따로 구현하지 않았다
=>
단순히 문제의 설명을 따라가지말고 문제 중간중간 판단해서 "묘듈화"!!

profile
공부방

0개의 댓글