반응형
리뷰
2D 시뮬레이션 구현 문제, 범위를 벗어난 조건을 만났을때 잘 처리해 주어야 한다.
문제 풀이
- init과 input, solution 세가지 구역으로 나누어 풀었다.
- init 함수에서는 ans값을 0으로 초기화, 웜홀 정보를 초기화 해주었다.
- input에서는 n값을 받고, n * n크기의 맵을 초기화, 만약 맵에서 6이상이 수가 있다면 웜홀을 초기화 해주었다.
- solution 함수에서는 맵 전체에서 0인 값을 만난다면 4방향으로 simulation을 돌려주는 브루트포스 역할
- simulation 함수에서는 실제로 핀볼이 2D 맵에서 왔다갔다 하고 얻은 점수를 출력해 준다.
- 핀볼이 시뮬레이션을 통해 얻은 가장 높은 값을 출력해 주면 된다.
참고 사항
simulation 함수 상세 내용
- 핀볼이 시작되는 좌표와 현재 핀볼의 방향을 매개변수로 받아온다.
- 각각을 nx, ny, nd 로 새로 초기화 해주고 점수를 나타낼 cnt 변수를 0으로 초기화 해준다.
- 무한루프를 실행하여 현재 진행방향으로 nx, ny 값을 알맞게 진행시켜 준다.
- 벽을 만난 경우를 맵 범위를 벗어난 상태로 인지하여 가장 먼저 조건을 만들어 주었다. 만약 맵 범위 밖으로 나갔을 경우 다시 이전 위치로 돌려놓은 뒤 방향을 반대로 설정해 주었다. 좌 ↔ 우, 상 ↔ 하 이런 식으로, 점수 1 증가
- 만약 현재 위치가 -1일 경우 블랙홀을 만난 경우이므로 break 처리해 준다.
- 만약 현재 위치가 초기에 매개변수로 받아온 x, y라면 처음 위치로 돌아온 경우이므로 break 처리해 준다.
- 만약 6 이상의 숫자를 만난 경우 웜홀을 만난 것이다. 각 반대 위치로 순간이동을 시켜준다.
- 만약 1 ~ 5 사이의 숫자를 만난 경우 블럭을 만난 것이다. 각 블럭에 알맞게 방향을 변환시켜 준다. 점수 1 증가
- while문이 break 되었을 경우 그 동안 모은 cnt 값을 리턴해 주고 최대값을 갱신해 준다.
정답 코드
#include<iostream>
#include<vector>
using namespace std;
int tc, n, w, ans;
int lst[101][101];
int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, -1, 1 };
int blocks[6][4] = {
{0, 0, 0, 0},
{1, 3, 0, 2},
{3, 0, 1, 2},
{2, 0, 3, 1},
{1, 2, 3, 0},
{1, 0, 3, 2}
};
struct WH {
int x, y;
};
vector<vector<WH>> worm;
void init() {
ans = 0;
for (auto& w : worm ) w.clear();
worm.resize(11);
}
void input() {
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> lst[i][j];
if (lst[i][j] >= 6) {
worm[lst[i][j]].push_back({ i, j });
}
}
}
}
int sumulation(int x, int y, int dir) {
int nx = x, ny = y, nd = dir, cnt = 0;
while (1) {
nx += dx[nd];
ny += dy[nd];
// 벽을 만난 경우
if (nx < 0 || ny < 0 || nx >= n || ny >= n) {
nx -= dx[nd];
ny -= dy[nd];
if (nd % 2) nd -= 1;
else nd += 1;
cnt++;
}
// 블랙홀을 만난 경우
if (lst[nx][ny] == -1) break;
// 시작 위치로 돌아온 경우
if (nx == x && ny == y) break;
// 웜홀을 만난 경우
if (lst[nx][ny] >= 6) {
int wormhole = lst[nx][ny];
WH wh1 = worm[wormhole][0];
WH wh2 = worm[wormhole][1];
if (wh1.x == nx && wh1.y == ny) nx = wh2.x, ny = wh2.y;
else nx = wh1.x, ny = wh1.y;
}
// 블럭을 만난 경우
if (1 <= lst[nx][ny] && lst[nx][ny] <= 5) {
nd = blocks[lst[nx][ny]][nd];
cnt++;
}
}
return cnt;
}
void solution() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (lst[i][j] == 0) {
for (int k = 0; k < 4; k++) {
ans = max(ans, sumulation(i, j, k));
}
}
}
}
}
int main() {
cin >> tc;
for (int c = 1; c <= tc; c++) {
init();
input();
solution();
cout << "#" << c << " " << ans << "\n";
}
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
백준 2644번 촌수계산 C++ BFS, 너비 우선 탐색 (0) | 2024.08.20 |
---|---|
백준 17472번 다리 만들기 2 C++ 구현, BFS, MST, 브루트포스 알고리즘 (0) | 2024.08.19 |
백준 14888번 연산자 끼워넣기 C++ 백트래킹, 재귀 (0) | 2024.08.19 |
SWEA 5658번 [모의 SW 역량테스트] 보물상자 비밀번호 C++ 문자열, 정렬 (0) | 2024.08.19 |
백준 2665번 미로만들기 C++ BFS, 최단 경로, 우선순위 큐 (0) | 2024.08.18 |