ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 17143 낚시왕
    Algorithm/구현(Brute force, Back tracking, etc.) 2021. 11. 26. 10:19
    728x90

    https://www.acmicpc.net/problem/17143

     

    17143번: 낚시왕

    낚시왕이 상어 낚시를 하는 곳은 크기가 R×C인 격자판으로 나타낼 수 있다. 격자판의 각 칸은 (r, c)로 나타낼 수 있다. r은 행, c는 열이고, (R, C)는 아래 그림에서 가장 오른쪽 아래에 있는 칸이다.

    www.acmicpc.net

     

     

     

    - 단순 빡구현 문제이다. 

     

    - 내가 구현한 알고리즘의 경우, 시간복잡도는 O(r^2c^2)이다.

     

    - shark가 위치한 좌표는 pair<pair<int,int>, pair<int, bool>> 자료형의 벡터로 관리했다. 왼쪽부터 각각 속력, 방향, 크기, 상어의 이동 여부를 의미한다. t가 c를 넘지 않을 동안 주어진 while문을 실행한다.

     

    - 땅과 가장 가까운 상어를 잡고, 이후 상어의 이동을 시작한다. 일단 상어가 이동할 거리를 단축시켜주어 시간을 줄이는데, 상어의 방향과 평행인 두 방향(상어의 방향이 북쪽인경우, 북쪽과 남쪽)을 고려해서 줄여준다. 예를들어 2,3에 위치한 상어의 방향이 북쪽이고, R의 크기가 5라면 상어는 (R-1) * 2번의 이동 후에 현재 위치 및 방향과 동일하게 있게 된다. 따라서, 상어의 속력을 (R-1)*2 로 나눈 나머지를 구해서 그것에 대한 이동만 구해주면 된다.

     

    - 다음으로, 상어의 이동시, 벽을 만났을 때이다. 상어가 만약 다음칸으로 이동하려는데, 해당 칸이 범위 밖이면 방향을 반대로 바꿔준다. 그 이후 한 칸을 전진하면 된다.

     

    - 다음으로 조심해야 할 것은 상어의 이동 여부이다. 만약 어떤 상어가 이동을 완료하였는데, 이중 for문을 돌다보니 이동을 마친 상어가 또 선택될 수 있다. 따라서, 해당 상어의 bool형을 보고, 만약 true이면 이동을 마친 것이므로 continue를 해 주면 된다. 

     

    - 이 모든 과정을 마쳤다면, 특정 칸에 여러 마리의 상어가 존재할 수 있다. 이 경우는 해당 칸을 sort를 해 주어서, 가장 큰 크기의 상어를 제외한 모든 상어들을 pop_back 해 주면 된다.

     

    - 여태까지 푼 삼성 기출문제중에 손에 꼽는 문제였다.. 엄청나게 어려웠다기보다는 세세한 구현사항이 많았어서 디버깅을 엄청 오래했다. 총 소요시간은 1시간 30분정도.. 삼성이 3시간내에 2문제를 풀어야하니 조금 더 속도를 높일 필요가 있는 것 같다.ㅠㅠ

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    vector <pair<pair<int, int>, pair<int, bool>>> shark[101][101];
    int dx[] = { -1,1,0,0 };
    int dy[] = { 0,0,1,-1 };
    
    bool compare(pair<pair<int, int>, pair<int, bool>> a, pair<pair<int, int>, pair<int, bool>> b) {
    	return a.second.first > b.second.first;
    }
    
    int main() {
    	int answer = 0;
    	int R, C, M;
    	cin >> R >> C >> M;
    	for (int i = 0; i < M; i++) {
    		int r, c, s, d, z;
    		cin >> r >> c >> s >> d >> z;
    		shark[r][c].push_back({ {s,d},{z,false} });
    	}
    	int t = 1;
    	while (t <= C) {
    		// 가장 가까운 상어 잡기
    		for (int i = 1; i <= R; i++) {
    			if (shark[i][t].size() != 0) {
    				answer += shark[i][t][0].second.first;
    				shark[i][t].pop_back();
    				break;
    			}
    		}
    		//상어 이동
    		for (int i = 1; i <= R; i++) {
    			for (int j = 1; j <= C; j++) {
    				if (shark[i][j].size() != 0) {
    					if (shark[i][j][0].second.second) continue;
    					int temp_s = shark[i][j][0].first.first;
    					int shark_d = shark[i][j][0].first.second;
    					int shark_z = shark[i][j][0].second.first;
    					// 이동 횟수를 최대한 줄여준다.
    					int real_s = temp_s % ((C - 1) * 2);
    					if (shark_d == 1 || shark_d == 2) {
    						real_s = temp_s % ((R - 1) * 2);
    					}
    					shark[i][j].erase(shark[i][j].begin());
    					int real_i = i; int real_j = j;
    					// 상어 이동
    					while (real_s--) {
    						if ((shark_d == 1 && real_i == 1) || (shark_d == 2 && real_i == R) || (shark_d == 3 && real_j == C) || (shark_d == 4 && real_j == 1)) {
    							if (real_i + dx[shark_d - 1] < 1 || real_i + dx[shark_d - 1] > R || real_j + dy[shark_d - 1] < 1|| real_j + dy[shark_d - 1] > C) {
    								if (shark_d % 2) shark_d += 1;
    								else shark_d -= 1;
    							}
    						}
    						real_i += dx[shark_d - 1];
    						real_j += dy[shark_d - 1];
    					}
    					shark[real_i][real_j].push_back({ { temp_s,shark_d }, {shark_z, true} });
    				}
    			}
    		}
    		for (int i = 1; i <= R; i++) {
    			for (int j = 1; j <= C; j++) {
    				if (shark[i][j].size() > 1) {
    					sort(shark[i][j].begin(), shark[i][j].end(), compare);
    					while (shark[i][j].size() > 1) shark[i][j].pop_back();
    				}
    				if(shark[i][j].size() == 1) shark[i][j][0].second.second = false;
    			}
    		}
    	
    		t++;
    	}
    
    	cout << answer;
    	return 0;
    }

    'Algorithm > 구현(Brute force, Back tracking, etc.)' 카테고리의 다른 글

    백준 17779 게리맨더링2  (0) 2021.11.30
    백준 17142 연구소3  (0) 2021.11.26
    백준 17144 미세먼지 안녕!  (0) 2021.11.19
    백준 16236 아기 상어  (0) 2021.11.19
    백준 16235 나무 재테크  (0) 2021.11.18

    댓글

Designed by Tistory.