Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- C++
- 크롬설치파일꺼짐
- 백준 14888번
- 백준 14503번
- chromeSetup.exe 안됨
- 크롬 설치 안됨
- ChromeStandaloneSetup64안됨
- 로봇청소기
- chromeSetup.exe꺼짐
- 삼성 sw 역량테스트
- 연산자 끼워넣기
- 크롬설치
- 바로꺼짐
Archives
- Today
- Total
공대생의 개발 일기장
22. [백준 17143번 / C++] 낚시왕 본문
https://www.acmicpc.net/problem/17143
17143번: 낚시왕
낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다.
www.acmicpc.net
구현은 정말 빨리 했는데... 14%에서 계속 시간초과가 난 문제다.
도대체 시간 초과가 어디서 나는걸까? 일단 코드를 보자.
#include<bits/stdc++.h>
using namespace std;
const int dy[] = {-1, 0, 1, 0};
const int dx[] = {0, 1, 0, -1};
int n, m, k, r, c, s, d, z, a[104][104], b[104][104], cnt, ret;
vector<tuple<int, int, int>> v; // 속도, 방향, 크기.
void catchFish(int cnt){
for(int i = 1; i <= n; i++){
if(a[i][cnt] != 0){
ret += get<2> (v[a[i][cnt] - 1]);
a[i][cnt] = 0;
break;
}
}
return;
}
pair<int, int> _move(int y, int x, int k){
int velo, dir, size;
tie(velo, dir, size) = v[k - 1];
while(velo--){
int ny = y + dy[dir];
int nx = x + dx[dir];
if(ny <= 0 || ny > n || nx <= 0 || nx > m){
dir = (dir + 2) % 4;
ny = y + dy[dir];
nx = x + dx[dir];
}
y = ny;
x = nx;
}
get<1>(v[k - 1]) = dir;
return {y, x};
}
void moveFish(){
memset(b, 0, sizeof(b));
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(a[i][j] != 0){
int ny, nx;
tie(ny, nx) = _move(i, j, a[i][j]);
if(b[ny][nx] != 0){
if(get<2>(v[b[ny][nx] - 1]) < get<2>(v[a[i][j] - 1])) b[ny][nx] = a[i][j];
}else b[ny][nx] = a[i][j];
a[i][j] = 0;
}
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
a[i][j] = b[i][j];
}
}
return;
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> n >> m >> k;
for(int i = 1; i <= k; i++){
cin >> r >> c >> s >> d >> z;
if(d == 1) d = 0;
else if(d == 2) d = 2;
else if(d == 3) d = 1;
else if(d == 4) d = 3;
a[r][c] = i;
v.push_back(make_tuple(s, d, z));
}
while(cnt < m + 1){
cnt++;
catchFish(cnt);
moveFish();
}
cout << ret << "\n";
}
아무리 생각해도 코드 상에서 시간초과가 날 곳은 상어가 움직이는 while문밖에 없었는데... 문제의 조건을 다시보니, 상어의 최대 개수는 10000개, 속력은 1000이므로 벌써 10^7이다. 근데 이것이 낚시왕이 100번의 움직임을 보여줄 수 있으니 총 10^9으로 시간초과가 나는 것이 당연하다. 이걸 왜 문제를 읽고 고려를 안했을까? 참~ 버릇을 들여야하는데...
그렇다면 한칸 한칸씩 이동하는 것이 아닌 다른 아이디어를 써야할 것 같은데!
놀랍게도 이전에 들었던 강의에 있었던 내용 아닌가? 당시 강의를 들을 때 알고리즘 초보였던 내가 너무 어려운 문제여서 그냥 넘기는 바람에 풀었던 기억조차 안났다...ㅠ
코드는 기존의 위의 코드에서 속도에 대한 범위를 제한할 수 있도록하는 한 줄만 추가하면된다. 백준 질문게시판에 이 부분은 많이 답변이 되어있으니 궁금하다면 그곳을 참고해보자.
'코딩 테스트 > 삼성 SW 역량 테스트 기출 문제' 카테고리의 다른 글
24. [백준 17142번 / C++] 연구소 3 (0) | 2024.03.25 |
---|---|
23. [백준 17140번 / C++] 이차원 배열과 연산 (0) | 2024.03.24 |
21. [백준 17144번 / C++] 미세먼지 안녕! (0) | 2024.03.22 |
20. [백준 16236번 / C++] 아기 상어 (0) | 2024.03.22 |
19. [백준 16235번 / C++] 나무 재테크 (0) | 2024.03.22 |