반응형
12100번 2048(Easy)
- 이해하기
- 한 번의 이동은 보드 위에 있는 블록을 같은 방향으로 이동시킨다.
- 이동했을 때 같은 값을 갖는 두 블록이 충돌하면 두 블록은 하나로 합쳐진다.
- 같은 이동에서 합쳐진 블록은 다른 블록과 다시 합쳐질 수 없다.
- 최대 5번의 이동을 통해 만들어 질 수 있는 블록의 최대값을 구한다.
- 블록을 최대 횟수까지 이동시키며 상태를 보는 완전탐색 문제.
-
구현하기
-
한번의 방향으로 이동시키면서 같은 값의 블록이 충돌하면 두 블록을 하나로 합치고 이미 합쳐진 블록은 다른 블록과 합쳐지지 못하게 check배열을 이용한다.
vector<vector<int>> move(vector<vector<int>> map, int dir) { vector<vector<int>> ret(N,vector<int>(N)); memset(check,false,sizeof(check)); if(dir == 0) { for(int i = 1; i < N; i++) { for(int j = 0; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(x-1 >= 0) { if(map[x-1][y] == 0) { map[x-1][y] = map[x][y]; map[x][y] = 0; } else { if(map[x-1][y] == map[x][y] and check[x-1][y] == false) { map[x-1][y] += map[x][y]; check[x-1][y] = true; map[x][y] = 0; break; } else break; } x -= 1; } } } } else if(dir == 1) { for(int i = N-2; i >= 0; i--) { for(int j = 0; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(x+1 < N) { if(map[x+1][y] == 0) { map[x+1][y] = map[x][y]; map[x][y] = 0; } else { if(map[x+1][y] == map[x][y] and check[x+1][y] == false) { map[x+1][y] += map[x][y]; check[x+1][y] = true; map[x][y] = 0; break; } else break; } x+=1; } } } } else if(dir == 2) { for(int i = 0; i < N; i++) { for(int j = 1; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(y-1 >= 0) { if(map[x][y-1] == 0) { map[x][y-1] = map[x][y]; map[x][y] = 0; } else { if(map[x][y-1] == map[x][y] and !check[x][y-1]) { map[x][y-1]*=2; check[x][y-1] = true; map[x][y] = 0; break; } else break; } y-=1; } } } } else if(dir == 3) { for(int i = 0; i < N; i++) { for(int j = N-2; j >= 0; j--) { if(map[i][j] == 0) continue; int x = i, y = j; while(y+1 < N) { if(map[x][y+1] == 0) { map[x][y+1] = map[x][y]; map[x][y] = 0; } else { if(map[x][y+1] == map[x][y] and !check[x][y+1]) { map[x][y+1]*=2; check[x][y+1] = true; map[x][y] = 0; break; } else break; } y+=1; } } } } for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { ret[i][j] = map[i][j]; } } return ret; }
-
최대 5번의 이동을 통해서 나올 수 있는 블록의 최대값을 구한다.
int solve(vector<vector<int>> map, int cnt) { if(cnt == 5) { int max = 0; for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if(max < map[i][j]) max = map[i][j]; } } return max; } int ret = 0; vector<vector<int>> t_map; for(int i = 0; i < 4; i++) { t_map = move(map,i); ret = max(ret,solve(t_map,cnt+1)); } return ret; }
-
-
전체 코드
#include <iostream> #include <cstring> #include <vector> using namespace std; bool check[20][20]; int N; vector<vector<int>> move(vector<vector<int>> map, int dir) { vector<vector<int>> ret(N,vector<int>(N)); memset(check,false,sizeof(check)); if(dir == 0) { for(int i = 1; i < N; i++) { for(int j = 0; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(x-1 >= 0) { if(map[x-1][y] == 0) { map[x-1][y] = map[x][y]; map[x][y] = 0; } else { if(map[x-1][y] == map[x][y] and check[x-1][y] == false) { map[x-1][y] += map[x][y]; check[x-1][y] = true; map[x][y] = 0; break; } else break; } x -= 1; } } } } else if(dir == 1) { for(int i = N-2; i >= 0; i--) { for(int j = 0; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(x+1 < N) { if(map[x+1][y] == 0) { map[x+1][y] = map[x][y]; map[x][y] = 0; } else { if(map[x+1][y] == map[x][y] and check[x+1][y] == false) { map[x+1][y] += map[x][y]; check[x+1][y] = true; map[x][y] = 0; break; } else break; } x+=1; } } } } else if(dir == 2) { for(int i = 0; i < N; i++) { for(int j = 1; j < N; j++) { if(map[i][j] == 0) continue; int x = i, y = j; while(y-1 >= 0) { if(map[x][y-1] == 0) { map[x][y-1] = map[x][y]; map[x][y] = 0; } else { if(map[x][y-1] == map[x][y] and !check[x][y-1]) { map[x][y-1]*=2; check[x][y-1] = true; map[x][y] = 0; break; } else break; } y-=1; } } } } else if(dir == 3) { for(int i = 0; i < N; i++) { for(int j = N-2; j >= 0; j--) { if(map[i][j] == 0) continue; int x = i, y = j; while(y+1 < N) { if(map[x][y+1] == 0) { map[x][y+1] = map[x][y]; map[x][y] = 0; } else { if(map[x][y+1] == map[x][y] and !check[x][y+1]) { map[x][y+1]*=2; check[x][y+1] = true; map[x][y] = 0; break; } else break; } y+=1; } } } } for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { ret[i][j] = map[i][j]; } } return ret; } int solve(vector<vector<int>> map, int cnt) { if(cnt == 5) { int max = 0; for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { if(max < map[i][j]) max = map[i][j]; } } return max; } int ret = 0; vector<vector<int>> t_map; for(int i = 0; i < 4; i++) { t_map = move(map,i); ret = max(ret,solve(t_map,cnt+1)); } return ret; } int main() { cin >> N; vector<vector<int>> map(N, vector<int>(N)); for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { cin >> map[i][j]; } } cout << solve(map,0) << '\n'; return 0; }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 13458번 시험 감독 (0) | 2019.10.03 |
---|---|
[백준] 3190번 뱀 (0) | 2019.10.03 |
[백준] 13460번 구슬 탈출2 (0) | 2019.10.03 |
7576. 토마토 (0) | 2018.11.15 |
1259. 팰린드롬수 (0) | 2018.11.13 |