새소식

코딩테스트/코드트리

[코드트리 챌린지] 금 채굴하기

  • -

[문제]

https://www.codetree.ai/cote/13/problems/gold-mining?&utm_source=clipboard&utm_medium=text 

 

코드트리 | 코딩테스트 준비를 위한 알고리즘 정석

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

 

[문제 풀이]

n * n 배열에서 금을 얻을때마다 m씩 얻고 마름모의 채굴비용은 KK+(K+1)(K+1) 로 소비될때 채굴비용이 음수가 되지 않는 내에서 최대 금을 몇개 얻을 수 있는지 요구하는 문제이다.

 

위의 그림의 마름모는 K가 1일때고 2일때는 아래와 같은 모습이다.

 

사실 잘 생각해보면 어딘가에서 유독 많이 본 모습이라고 느낄만한데 바로 BFS 알고리즘을 돌릴때 위의 그림들과 같이 커지는 모습을 눈치챌 수 있다.

 

그러면 해당 문제는 이제 0,0부터 n - 1, n - 1까지 돌리면서 해당 위치에서 bfs의 넓이가 0일때부터 bfs의 넓이가 n일때까지 돌려주는 것을 요구하는 문제로 바뀐다.

추가로 bfs를 n번까지만 하면 되는 이유는 0,0의 위치에서 볼때 n까지 돌리면 우측 하단에 공간이 남을 수 있지만 가운데 좌표에서 n일때까지 돌리면 모든 공간을 채울 수 있으므로 굳이 0,0에서 모든 공간을 채울 필요가 없기 때문이다.

[회고]

bfs를 n번 돌리는 부분에서 처음에 실수를 했다. 두번째에는 이를 해결하기 위해서 내부에 cur 변수를 추가로 뒀지만 조금 더 다른 방법이 없나 확인을 해보자.

[코드]

#include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; int n,m; int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; int boards[51][51]; int visited[51][51]; bool inRange(int x, int y){ if(x >= 0 && x < n && y >= 0 && y < n){ return true; } return false; } void visitedClear(){ for(int i = 0;i<n;i++){ for(int j = 0;j<n;j++){ visited[i][j] = 0; } } return; } int four(int n){ int answer = 1; for(int i = 0;i<n;i++){ answer *= 4; } return answer + 1; } int bfs(int r, int c, int n){ int answer = 0; visitedClear(); queue<pair<pair<int,int>,int > > q; q.push(make_pair(make_pair(r,c),0) ); if(boards[r][c] == 1){ answer += m; } visited[r][c] = 1; while(q.size() > 0){ int curX = q.front().first.first; int curY = q.front().first.second; int cur = q.front().second; if(cur == n){ break; } q.pop(); for(int i = 0;i<4;i++){ int nextX = curX + dx[i]; int nextY = curY + dy[i]; if(inRange(nextX,nextY) == true && visited[nextX][nextY] == 0){ //만일 코인이라면. if(boards[nextX][nextY] == 1){ // cout<<"next : "<<nextX<<" "<<nextY<<" "; answer += m; } visited[nextX][nextY] = 1; q.push(make_pair(make_pair(nextX,nextY),cur + 1 ) ); } } } return answer; } int main() { cin>>n>>m; for(int i = 0;i<n;i++){ for(int j = 0;j<n;j++){ cin>>boards[i][j]; } } //1. 모두 돌기. //2. 마름모 키우기 => bfs n번 범위. // cout<<"마름모 돌리기 : "<<endl; int answer = 0; for(int i = 0;i<n;i++){ for(int j = 0;j<n;j++){ for(int k = 0;k<n;k++){ int temp = bfs(i,j,k); // cout<<"i : "<<i<<" j : "<<j<<" k : "<<k<<" "; // cout<<temp<<endl; if( temp - ((k * k) + ( k + 1) * (k + 1)) >= 0 ){ answer = max(answer, temp / m); } // cout<<temp<<" "; } // cout<<endl; } // cout<<endl; } cout<<answer<<endl; return 0; }

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.