지우너
[코드트리] 구슬의 이동 C++ 본문
문제
https://www.codetree.ai/missions/2/problems/marble-movement?&utm_source=clipboard&utm_medium=text
코드트리 | 코딩테스트 준비를 위한 알고리즘 정석
국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.
www.codetree.ai
계획세우기
marble[i][0]:구슬의 번호(들어온 순서), marble[i][1]: x, marble[i][2]: y, marble[i][3]: dir, marble[i][4]: v(1초에 움직이는 양)
아래 과정을 time 동안 반복
1. 구슬 이동
- dx, dy이용. marble[i][4]에 들어있는 값만큼 marble[i][3] 방향으로 이동
- 범위를 벗어나면 방향을 바꾸고 다음 좌표 재설정
- 변경된 좌표 및 방향을 벡터에 갱신
2. 구슬이 k보다 많이 들어 있는 칸 찾기
3. 해당 칸에 있는 구슬 중 우선 순위가 낮은 것 지우기
- (해당 칸에 구슬이 k개 이하가 될 때까지 반복): 가장 우선순위가 낮은 값을 범위 밖의 값(x=-1, y=-1, v=100)으로 설정
- 재정렬(v가 큰 수가 뒤로 정렬되도록 했기 때문에 없앨 구슬은 뒤쪽에 정렬된다.)
- 뒤쪽에 있는 값을 pop_back으로 없애준다.
아래는 틀렸던 테스트 케이스가 왜 틀린 건지 보려고 구글 슬라이드로 시뮬레이션 한 것
코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, m, t, k;
int arr[51][51];
vector<vector<int> > marble;
bool InRange(int x, int y){
return x>=0 && x<n && y>=0 && y<n;
}
int DirConvertToInt(char dir){
if (dir=='L') return 0;
if (dir=='U') return 1;
if (dir=='R') return 2;
if (dir=='D') return 3;
return -1;
}
// 우선순위: 속도가 빠른 구슬이 높음(같을 경우 구슬의 번호가 더 큰 구슬이 높음)
// 구슬의 번호는 입력된 순서
// 우선순위가 낮은 순서로 없앰
bool cmp(vector<int> &v1, vector<int> &v2){
if(v1[4]==v2[4]) return v1[0]<v2[0];
return v1[4]<v2[4];
}
void MoveMarble(){
//L(0,-1) U(-1,0) R(0,1) D(1,0)
int dx[4]={0, -1, 0, 1};
int dy[4]={-1, 0, 1, 0};
for(int i=0; i<m; ++i){
int dir=marble[i][3];
int move=marble[i][4];
while (move--){
int nx = marble[i][1]+dx[dir];
int ny = marble[i][2]+dy[dir];
if(!InRange(nx, ny)){
dir= (dir+2)%4;
nx = marble[i][1]+dx[dir];
ny = marble[i][2]+dy[dir];
}
arr[marble[i][1]][marble[i][2]]--;
marble[i][1]=nx;
marble[i][2]=ny;
marble[i][3]=dir;
arr[nx][ny]++;
}
}
}
void RemoveMarble(int x, int y){
// k이하가 될 때까지 우선순위에 따라
while (arr[x][y]>k){
for(int i=0; i<marble.size(); i++){
if(marble[i][1]==x && marble[i][2]==y){
marble[i][1]=-1;
marble[i][2]=-1;
marble[i][4]=100; // 1<=v<=10
arr[x][y]--;
m--;
break;
}
}
}
sort(marble.begin(), marble.end(), cmp);
while(marble.size()>m){
marble.pop_back();
}
}
void Progress(){
// t초 동안 반복
while(t--){
//1. 구슬 이동
MoveMarble();
//2. 구슬이 k개 이상이 칸 찾기
for(int i=0; i<n; ++i){
for(int j=0; j<n; ++j){
// 3. k이상이 칸에 있는 구슬 우선순위에 따라 삭제
if(arr[i][j]>k) RemoveMarble(i, j);
}
}
}
}
int main() {
// input
cin >> n >> m >> t >> k;
for(int i=0; i<m; ++i){
int r, c, v;
char dir;
cin >> r >> c >> dir >> v;
marble.push_back({i, r-1, c-1, DirConvertToInt(dir), v});
arr[r-1][c-1]=1;
}
sort(marble.begin(), marble.end(), cmp);
Progress();
// output
cout << m << '\n';
return 0;
}
'Problem Solving' 카테고리의 다른 글
[코드트리] 특정 조건에 맞게 k개 중에 1개를 n번 뽑기 C++ (0) | 2024.06.23 |
---|---|
[코드트리] 합쳐지는 구슬들 C++ (0) | 2024.06.22 |
[코드트리] 쌓인 숫자의 순차적 이동 C++ (0) | 2024.06.20 |
[코드트리] 벽이 있는 충돌 실험 C++ (0) | 2024.06.19 |
[코드트리] 숫자의 순차적 이동 C++ (0) | 2024.06.18 |