오늘의 알고리즘
[C++] 백준 12100 2048 (Easy)
하늘하늘 .
2022. 12. 8. 22:27
#include <iostream>
#include <algorithm>
#include <vector>
int N = 0;
long long ans = 0;
long long GetMax(std::vector<std::vector<long long>> board)
{
long long temp = 0;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
temp = std::max(temp, board[i][j]);
}
}
return temp;
}
std::vector<std::vector<long long>> Right(std::vector<std::vector<long long>> board)
{
std::vector<std::vector<bool>> check(N, std::vector<bool>(N, false));
for (int i = 0; i < N; ++i)
{
for (int j = N - 2; j >= 0; --j)
{
if (!board[i][j])
continue;
for (int k = j + 1; k < N; ++k)
{
if (board[i][k] == board[i][k - 1] && !check[i][k])
{
board[i][k] *= 2;
board[i][k - 1] = 0;
check[i][k] = true;
break;
}
else if (!board[i][k])
{
board[i][k] = board[i][k - 1];
board[i][k - 1] = 0;
}
else
break;
}
}
}
return board;
}
std::vector<std::vector<long long>> Left(std::vector<std::vector<long long>> board)
{
std::vector<std::vector<bool>> check(N, std::vector<bool>(N, false));
for (int i = 0; i < N; ++i)
{
for (int j = 1; j < N; ++j)
{
if (!board[i][j])
continue;
for (int k = j - 1; k >= 0; --k)
{
if (board[i][k] == board[i][k + 1] && !check[i][k])
{
board[i][k] *= 2;
board[i][k + 1] = 0;
check[i][k] = true;
break;
}
else if (!board[i][k])
{
board[i][k] = board[i][k + 1];
board[i][k + 1] = 0;
}
else
break;
}
}
}
return board;
}
std::vector<std::vector<long long>> Down(std::vector<std::vector<long long>> board)
{
std::vector<std::vector<bool>> check(N, std::vector<bool>(N, false));
for (int i = 0; i < N; ++i)
{
for (int j = N - 2; j >= 0; --j)
{
if (!board[j][i])
continue;
for (int k = j + 1; k < N; ++k)
{
if (board[k][i] == board[k - 1][i] && !check[k][i])
{
board[k][i] *= 2;
board[k - 1][i] = 0;
check[k][i] = true;
break;
}
else if (!board[k][i])
{
board[k][i] = board[k - 1][i];
board[k - 1][i] = 0;
}
else
break;
}
}
}
return board;
}
std::vector<std::vector<long long>> Up(std::vector<std::vector<long long>> board)
{
std::vector<std::vector<bool>> check(N, std::vector<bool>(N, false));
for (int i = 0; i < N; ++i)
{
for (int j = 1; j < N; ++j)
{
if (!board[j][i])
continue;
for (int k = j - 1; k >= 0; --k)
{
if (board[k][i] == board[k + 1][i] && !check[k][i])
{
board[k][i] *= 2;
board[k + 1][i] = 0;
check[k][i] = true;
break;
}
else if (!board[k][i])
{
board[k][i] = board[k + 1][i];
board[k + 1][i] = 0;
}
else
break;
}
}
}
return board;
}
void DFS(int count, std::vector<std::vector<long long>> board)
{
ans = std::max(ans, GetMax(board));
if (count == 5)
return;
DFS(count + 1, Right(board));
DFS(count + 1, Left(board));
DFS(count + 1, Up(board));
DFS(count + 1, Down(board));
}
int main()
{
std::cin >> N;
std::vector<std::vector<long long>> board(N, std::vector<long long>(N));
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
std::cin >> board[i][j];
}
}
DFS(0, board);
std::cout << ans;
return 0;
}
DFS로 모든 방향으로 5번 회전시킵니다.
회전 시킬 때 숫자가 없을 경우 다음으로,
번호가 있다면 옆으로 미는데 같은 숫자라면 합칩니다.
(이 때, 합쳐지면 다시 합쳐지면 안되기 때문에 check로 다음에 합쳐지지 않게 만듭니다.)
5번 전부 옮겼다면 바로 Max체크를 합니다.