17143 낚시왕
문제 링크
알고리즘 문제 중 구현, 시뮬레이션 문제류를 풀 때 기능 분리에만 목적을 두지 말고 좀 더 쉬운 로직을 찾기 위해 노력해야함.
main.cpp 주요 함수들 : 상어먹기, 방향전환, 상어 움직이기, 시뮬레이션 실행 하지만 과도한? 기능 분리 + 세부 연산 실패로 문제 푸는 데 오래걸림
내가 생각한 연산방법
- moveshark
예를 들어 UP은 row에서 spd만큼 올라가야 한다. spd가 row보다 작은경우를 제외하고, row가 spd보다 작거나 같은 경우 행렬의 범위를 벗어나게 된다. 더 나아가 spd와 row의 뺀값의 범위에 따라 방향이 바뀌거나 원래 방향으로 돌아오게 된다. 방향이 바뀌는 경우는 rest_spd(뺀 나머지 속도)가 R(전체 행 길이) - 1이하인 경우 방향이 바뀌고 초과한 경우 방향이 원래로 돌아오게 된다. 이 사실을 이용하여 계산하여 함수를 작성하였으나 너무 조잡하고 길다고 느껴져 moveshark2를 구현하게 되었다.
- moveshark2
위와 같이 구현하면 속도는 더 빠를지 언정 출제자의 목적에 부합하는 풀이였는지 애매모호하여 moveshark2를 작성하게 되었다. moveshark2는 솔직히 잘 짠 코드라고 보기 어렵다. if문에 따라 나누기 보다 차라리 switch로 UP, DOWN, LEFT, RIGHT에 따라 초기화를 개별적으로 해줬으면 좋았을 것 같다. movedistance로 while문을 돌린것은 괜찮은 아이디어였던것 같다. 부가적으로 spd가 0인 경우도 좀 더 깔끔하게 처리할 수 있을것 같다.
- 다른사람 풀이
moveshark2 와 핵심 로직은 비슷하다. 배울점으로는 struct를 이용하여 shark를 정의하여 좀 더 가독성 높은 코드를 작성하였다는 점이 있다.
상어의 잡기와 이동을 for문에 전부 넣을 수 있다는 아이디어를 생각하지 못한것이 아쉬웠다.
내 코드
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
const int UP = 1;
const int DOWN = 2;
const int RIGHT = 3;
const int LEFT = 4;
using namespace std;
struct shark
{
int r, c, s, d, z;
shark(int _r, int _c, int _s, int _d, int _z) : r(_r), c(_c), s(_s), d(_d), z(_z){}
};
int mat[101][101];
int R, C, M;
vector<shark> slist;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> R >> C >> M;
int r, c, s, d, z, ret = 0;
while (M--)
{
cin >> r >> c >> s >> d >> z;
if (d == UP || d == DOWN)
s %= 2 * (R - 1);
else
s %= 2 * (C - 1);
mat[r][c] = z;
slist.push_back(shark( r, c, s, d, z ));
}
for (int t = 1; t <= C; t++)
{
for (int row = 1; row <= R; row++)
{
if (mat[row][t])
{
ret += mat[row][t];
mat[row][t] = 0;
break;
}
}
vector<shark> new_slist;
for (shark s : slist)
{
if (mat[s.r][s.c] != s.z)
continue;
int spd = s.s;
while (spd)
{
switch (s.d)
{
case UP:
s.r -= spd;
if (s.r <= 0) {
spd = 1 - s.r;
s.r = 1;
s.d = DOWN;
}
else
spd = 0;
break;
case DOWN:
s.r += spd;
if (s.r > R) {
spd = s.r - R;
s.r = R;
s.d = UP;
}
else
spd = 0;
break;
case RIGHT:
s.c += spd;
if (s.c > C) {
spd = s.c - C;
s.c = C;
s.d = LEFT;
}
else
spd = 0;
break;
case LEFT:
s.c -= spd;
if (s.c <= 0) {
spd = 1 - s.c;
s.c = 1;
s.d = RIGHT;
}
else
spd = 0;
break;
}
}
new_slist.push_back(s);
}
slist.swap(new_slist);
for (int row = 1; row <= R; row++) for (int col = 1; col <= C; col++)
{
mat[row][col] = 0;
}
for (shark s : slist)
{
if (mat[s.r][s.c] < s.z)
mat[s.r][s.c] = s.z;
}
}
cout << ret << "\n";
}
댓글남기기