반응형
리뷰
https://www.acmicpc.net/problem/17143
상어가 다른 상어를 잡아먹으면 잡아먹은 상어만큼 몸집이 커지는 줄 알았다...
오히려 더 어렵게 생각해서 한번 Fail을 받은 문제
전역 변수
- r : 맵의 세로 길이를 저장할 변수
- c : 맵의 가로 길이를 저장할 변수
- m : 상어의 개수를 저장할 변수
- ans : 정답을 저장할 변수
- lst : 맵 정보를 저장하기 위한 정수형 2차 배열
- dx, dy : 4방향 탐색을 하기 위한 방햘 배열
- Shark : 상어의 정보를 정의한 구조체, 상어의 번호 index, 위치 x, y, 속도 s, 방향 d, 크기 z를 저장하고, 상어의 크기 z를 기준으로 내림차순 정렬하는 비교 함수를 갖는다.
- sharks : 상어의 정보를 저장할 Shark타입의 배열
함수
1. input
void input()
맵과 상어 정보를 입력 받기 위한 함수
- r, c, m을 입력 받고, 1부터 m까지 for문을 개행해 준다.
- 1~m번의 상어 정보를 입력 받아 맵 상에 인덱스를 배치하고 sharks배열을 초기화 해준다.
- 이때 방향 배열은 -1만큼 감소시켜 0-based-indexing을 해주었다, 근데 딱히 필요 없는듯?
2. solution
void solution()
낚시왕을 이동시키며 문제에서 주어진 1, 2, 3번 로직을 수행하는 함수
- col을 0으로 초기화 해주고, col을 후위 증가 시켜주면서 c보다 작을 경우 while문을 수행한다.
- row를 0으로 초기화 해주고, row를 후위 증가 시켜주면서 r보다 작을 경우 while문을 수행한다.
- 맵 상에서 상어를 만난 경우 그 상어의 크기만큼 ans에 더해준 뒤 맵에서 0으로 바꿔주고 break 처리한다.
- Shark타입의 우선순위 큐 pq를 초기화 하고 r * c크기의 맵 정보를 순회한다.
- 상어를 만난 경우 맵 상에서 0으로 변경해 준 후 move함수를 통해 상어를 이동시켜 준다.
- 이동시킨 상어 정보를 최신화 해준 뒤 pq에 삽입해 준다.
- pq가 빌 때 까지 while루프를 개행하고, 매 루프마다 상어를 한개씩 꺼내어 준다.
- 이동 후 좌표에 상어가 이미 존재할 경우 continue처리를, 비어있다면 상어의 인덱스를 맵에 배치해 준다.
3. Move
Shark move(Shark& shark)
상어가 움직이는 시뮬레이션을 진행할 함수
- 매개변수로 Shark타입의 상어 정보 shark를 참조로 받아준다.
- shark의 방향이 상하, 좌우인 경우를 나누어서 이동시켜 준다.
- 상하 이동인 경우 변수 remain에 상어의 속도를 맵의 세로크기 - 1의 2배를 해준 값으로 나눈 나머지를 저장한다.
- 정수형 cx에 상어의 현재 x좌표 위치를 저장해 준다.
- remain만큼 while루프를 수행하고, cx가 1이라면 방향을 1로, cx가 r이라면 방향을 0으로 바꿔준다.
- 현재 상어의 방향으로 이동을 수행해 준다.
- 최종적으로 cx좌표를 상어의 x좌표로 갱신해 준 뒤 shark를 리턴해 준다.
- 좌우 이동인 경우도 위와 로직이 같으며 방향 배열, cy, 맵의 가로길이를 참조해 로직을 구성했다.
4. print
void print(int fisher)
시뮬레이션을 디버깅 하기 위한 함수
- 매개변수로 현재 낚시왕이 있는 열의 위치 fisher를 전달받는다.
- (r + 1) * c 크기의 for문을 개행해 준다.
- i가 0이면서 j가 fisher라면 F를 출력해 준 뒤 continue처리해 준다.
- 아니라면 맵의 정보를 출력해 준다.
- 출력 후 fisher를 한번 더 출력하여 진행 후 몇 초가 지났는지를 명시해 준다.
문제풀이
- input함수를 통해 맵과 상어 정보를 입력 받아준다.
- solution함수를 통해 낚시왕이 이동하면서 물고기를 잡고, 물고기의 이동을 시뮬레이션 해준다.
- ans에 저장된 값을 출력해 준다.
트러블 슈팅
- 상어가 다른 상어를 잡아먹은 경우 잡아 먹은 상어의 크기만큼 더 커지는 것으로 이해했다.
- 상어의 크기를 커지게 하는 로직을 삭제하고 continue처리로 변경해 주었더니 AC를 받았다.
참고 사항
- 상어의 속도가 최대 1000이므로 이동하는 횟수를 적당히 줄여줄 수록 시간의 영향을 덜 받을 듯 하다.
정답 코드
#include<iostream>
#include<queue>
using namespace std;
int r, c, m, ans;
int lst[101][101];
int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
struct Shark {
int index, x, y, s, d, z;
bool operator<(const Shark& other) const {
return z < other.z;
}
};
Shark sharks[10001];
void input() {
cin >> r >> c >> m;
for (int i = 1; i <= m; ++i) {
int x, y, s, d, z; cin >> x >> y >> s >> d >> z;
lst[x][y] = i;
sharks[i] = { i, x, y, s, d - 1, z };
}
}
Shark move(Shark& shark) {
if (shark.d == 0 || shark.d == 1) {
int remain = shark.s % ((r - 1) * 2);
int cx = shark.x;
while (remain--) {
if (cx == 1) shark.d = 1;
else if (cx == r) shark.d = 0;
cx += dx[shark.d];
}
shark.x = cx;
return shark;
}
if (shark.d == 2 || shark.d == 3) {
int remain = shark.s % ((c - 1) * 2);
int cy = shark.y;
while (remain--) {
if (cy == 1) shark.d = 2;
else if (cy == c) shark.d = 3;
cy += dy[shark.d];
}
shark.y = cy;
return shark;
}
}
void print(int fisher) {
for (int i = 0; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
if (i == 0 && j == fisher) {
cout << 'F' << " ";
continue;
}
cout << lst[i][j] << " ";
}
cout << "\n";
}
cout << fisher << "\n";
}
void solution() {
int col = 0;
while (col++ < c) {
//print(col);
int row = 0;
while (row++ < r) {
if (lst[row][col]) {
ans += sharks[lst[row][col]].z;
lst[row][col] = 0;
break;
}
}
priority_queue<Shark> pq;
for (int i = 1; i <= r; ++i) {
for (int j = 1; j <= c; ++j) {
if (lst[i][j]) {
Shark& shark = sharks[lst[i][j]];
lst[i][j] = 0;
Shark moved_shark = move(shark);
sharks[moved_shark.index] = moved_shark;
pq.push(sharks[moved_shark.index]);
}
}
}
while (!pq.empty()) {
Shark shark = pq.top(); pq.pop();
if (lst[shark.x][shark.y]) continue;
else lst[shark.x][shark.y] = shark.index;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
input();
solution();
cout << ans;
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
[G2] 백준 1365번 꼬인 전깃줄 C++ 이분 탐색, LIS (0) | 2025.01.23 |
---|---|
[G1] 백준 13459번 구슬 탈출 C++ 구현, 시뮬레이션, 너비 우선 탐색 (0) | 2025.01.23 |
[G1] 백준 11689번 GCD(n, k) = 1 C++ 정수론, 오일러 피 함수 (0) | 2025.01.21 |
[P4] 백준 5670번 휴대폰 자판 C++ 트라이, 메모리 풀 (0) | 2025.01.20 |
[S1] 백준 2468번 안전 영역 C++ 너비 우선 탐색, 플러드 필 (0) | 2025.01.20 |