인프런 커뮤니티 질문&답변
17143 낚시왕 문제 질문
작성
·
359
0
안녕하세요 17143 낚시왕 문제 풀다가 질문 생겨서 글 올립니다.
http://boj.kr/086861b125384b6caf2d251eb1c186ef
저는 위와 같이 코드를 작성하였는데, 답은 맞는 것 같지만 시간 초과가 납니다.
제 코드 중 시간 초과를 일으킬만한 부분 혹시 알려주실 수 있을까요?
답변 1
0
안녕하세요 bunny님ㅎㅎ
이거 확인해봤는데 그렇게 불필요한 로직은 없고 걸리는 건 2가지 인것 같은데 1. eat_shark 2. pick_shark 부분입니다.
이거 주석달았으니 참고 부탁드리구요. eat_shark 답변 부탁드려요
나머지 부분은 잘 짜셨어요 ㅎㅎ
shark[visited[shark[i][0]][shark[i][1]]][4]이부분은 좀 그렇긴 하지만요. 근데 이거 for(int i : 이렇게 하려고 해도 밑에 shark 인덱스를 기반으로 수정하려고 어쩔 수 없이 한 것같은데... 좀 고민이 필요한 코드인 것 같긴해요.
#include <iostream>
#include <vector>
#include <memory.h>
using namespace std;
int R, C, m;
int r, c, s, d, z;
vector<vector<int>> shark;
// 그 곳에 있는 상어 중 사이즈가 가장 큰 상어의 인덱스
int visited[104][104];
int deep[104];
int ans;
int now_pos;
// 상어 움직임
void move_shark()
{
for (int i = 0; i < shark.size(); i++)
{
// 죽은 상어 패스
if (shark[i][5] == 1) continue;
// 상어 움직임 // 스피드
for (int j = 0; j < shark[i][2]; j++)
{
//이동방향
if (shark[i][3] == 1)
{
if (shark[i][0] != 1) shark[i][0] -= 1;
else
{
shark[i][0] += 1;
shark[i][3] = 2;
}
}
else if (shark[i][3] == 2)
{
if (shark[i][0] != R) shark[i][0] += 1;
else
{
shark[i][0] -= 1;
shark[i][3] = 1;
}
}
else if (shark[i][3] == 3)
{
if (shark[i][1] != C) shark[i][1] += 1;
else
{
shark[i][1] -= 1;
shark[i][3] = 4;
}
}
else
{
if (shark[i][1] != 1) shark[i][1] -= 1;
else
{
shark[i][1] += 1;
shark[i][3] = 3;
}
}
}
}
return;
}
// 상어 잡아먹음
void eat_shark()
{
// 이동하기전 샤크와 이동한 후의 샤크를 어떻게 구분?
// 이동하기 전 >> visited 로 걸고
// 이동 한후 >> visited와 shark를 비교해야 하는 거 아님?
memset(visited, -1, sizeof(visited));
for (int i = 0; i < shark.size(); i++)
{
// 죽은 상어 패스
if (shark[i][5] == 1) continue;
// 아무 상어도 없어
if (visited[shark[i][0]][shark[i][1]] == -1)
{
visited[shark[i][0]][shark[i][1]] = i;
}
// 어떤 상어가 있어
else
{
// 원래가 있던 상어가 커
if (shark[visited[shark[i][0]][shark[i][1]]][4] > shark[i][4])
{
// 들어온 상어 죽음
shark[i][5] = 1;
}
// 지금이 커
else
{
// 원래 있던 상어 죽음
shark[visited[shark[i][0]][shark[i][1]]][5] = 1;
visited[shark[i][0]][shark[i][1]] = i;
}
}
}
return;
}
// 상어 줍기
void pick_shark(int now_pos)
{
//조금 더 단순화 시켜보자. 제 코드 참고해주세요.
memset(deep, -1, sizeof(deep));
// 그 곳에 있는 상어의 인덱스
for (int i = 0; i < shark.size(); i++)
{
// 죽은 상어 패스
if (shark[i][5] == 1) continue;
// i로 만들어놓고.
//deep 에 r을 담는다. 두개 이상의 상어가 있는 경우는 x
if (shark[i][1] == now_pos)
{
deep[shark[i][0]] = i;
}
}
//담은 것중에서 + 죽은 상어 break
for (int i = 1; i <= R; i++)
{
if (deep[i] > -1)
{
ans += shark[deep[i]][4];
// 주운 상어
shark[deep[i]][5] = 1;
break;
}
}
return;
}
int main()
{
cin >> R >> C >> m;
//good
for (int i = 0; i < m; i++)
{
cin >> r >> c >> s >> d >> z;
vector<int> v = { r,c,s,d,z,0 };
shark.push_back(v);
}
for (int i = 1; i <= C; i++)
{
now_pos = i;
pick_shark(now_pos);
move_shark();
eat_shark();
}
cout << ans << "\n";
return 0;
}일단 제가 첨에 좀 이상하다고 한 부분 있잖아요. 해당 부분 나름 최적화 시켰는데요.
그래도 시간초과가 뜨네요. 근데 원래는 14%에서 시간초과인데 지금은 15%이긴 한데...
일단 코드는 다음과 같아요.
http://boj.kr/9bff3aade2de45f6825634b3f2fafef0
아. 알았다.
이부분이요. 상어움직임을 O(n)만에 하잖아요. 이걸 O(1)로 바꿔보실래요? 제 코드 보시면 O(1)로 하고 있는데 해당 부분 참고해서요.
// 상어 움직임
for (int j = 0; j < shark[i][2]; j++)bunny님 안녕하세요. ㅎㅎ
낚시왕 설명 강의 영상 제가 다시 찍어서 올렸으며 해설코드도 수정해서 다시 올렸습니다.
해당 부분 참고하시면 코드 고쳐나가실 때 도움이 되실 거에요.ㅎㅎ
참고부탁드립니다.
아 근데 용량 제한 걸렸네요.. ㅠ
내일 업로드 될거에요. ㅎㅎ
감사합니다.






제가 변수 명을 좀 헷갈리게 적은 것 같아요
보통 설명하실 때 현재 지도를 나타낼 때 a 2차원 배열로 두신걸 제가 visited라고 명명했네요
visited 2차원 배열에는 현재 지도 상에 존재하는 shark의 인덱스를 넣었습니다.
상어가 없으면 -1을 넣었구요.