#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. 승패 판단을 함수로 따로 구현하지 않았다
=>
단순히 문제의 설명을 따라가지말고 문제 중간중간 판단해서 "묘듈화"!!