컴퓨터 공학 기초/알고리즘 (브루트포스)
백준 12100 ( Easy)
JongSeok_12
2020. 7. 14. 15:05
https://www.acmicpc.net/problem/12100
12100번: 2048 (Easy)
첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2
www.acmicpc.net
문제 풀이 방법
1. 오른쪽, 왼쪽, 위, 아래 방향으로 map 배열의 요소를 이동시켜주는 함수
2. 위에서 만든 함수의 각 동작을 DFS로 완전탐색 시키며 중복순열을 이용한다. ( 위, 위, 위, 위, 위 -> 위 위 위 위 아래 -> 위 위 위 위 왼 -> 위 위 위 위 오 )
3. max 회전 횟수인 5번일때 map 배열을 최대값 추출 후 최대값 갱신
위의 문제는 사실 풀이는 쉽지만 오른쪽, 위, 아래, 왼쪽 방향을 재각각 움직여 주는 노가다가 필요하기 때문에 Queue를 이용하여 0이 아닌 값들만 push 후 기존에 map의 값은 0으로 초기화 한다. 그 뒤 큐에 front에 위치한 정보를 가져 오면서 map배열의 가장자리부터 채워 넣는다. 이때 중요한것은 바뀌기 전 map 배열의 정보를 백업한 뒤 재귀가 끝난 뒤 다시 바뀌기 전의 map 배열 상태로 돌려놓는 작업을 해야한다.
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
int map[20][20];
int maxx = 0;
int n;
int getMax(){
int ma = 0;
for (int i = 0; i < n; ++i){
for (int j = 0; j < n; ++j){
if (ma < map[i][j]) ma = map[i][j];
}
}
return ma;
}
void move_map(int dir){
queue<int> qu;
// up
if (dir == 1){
for (int i = 0; i < n; ++i){
int idx = 0;
for (int j = 0; j < n; ++j){
if (map[j][i] > 0) {
qu.push(map[j][i]);
map[j][i] = 0;
}
}
while (!qu.empty()){
if (map[idx][i] == 0){
map[idx][i] = qu.front();
qu.pop();
}
else{
if (map[idx][i] == qu.front()){
map[idx][i] *= 2;
++idx;
qu.pop();
}
else {
idx++;
map[idx][i] = qu.front();
qu.pop();
}
}
}
}
}
// down
if (dir == 2){
for (int i = 0; i < n; ++i){
int idx = n - 1;
for (int j = n - 1; j >= 0; --j){
if (map[j][i] > 0) {
qu.push(map[j][i]);
map[j][i] = 0;
}
}
while (!qu.empty()){
if (map[idx][i] == 0){
map[idx][i] = qu.front();
qu.pop();
}
else{
if (map[idx][i] == qu.front()){
map[idx][i] *= 2;
--idx;
qu.pop();
}
else {
--idx;
map[idx][i] = qu.front();
qu.pop();
}
}
}
}
}
// left
if (dir == 3){
for (int i = 0; i < n; ++i){
int idx = 0;
for (int j = 0; j < n; ++j){
if (map[i][j] > 0) {
qu.push(map[i][j]);
map[i][j] = 0;
}
}
while (!qu.empty()){
if (map[i][idx] == 0){
map[i][idx] = qu.front();
qu.pop();
}
else{
if (map[i][idx] == qu.front()){
map[i][idx] *= 2;
++idx;
qu.pop();
}
else {
++idx;
map[i][idx] = qu.front();
qu.pop();
}
}
}
}
}
// right
if (dir == 4){
for (int i = 0; i < n; ++i){
int idx = n - 1;
for (int j = n - 1; j >= 0; --j){
if (map[i][j] > 0) {
qu.push(map[i][j]);
map[i][j] = 0;
}
}
while (!qu.empty()){
if (map[i][idx] == 0){
map[i][idx] = qu.front();
qu.pop();
}
else{
if (map[i][idx] == qu.front()){
map[i][idx] *= 2;
--idx;
qu.pop();
}
else {
--idx;
map[i][idx] = qu.front();
qu.pop();
}
}
}
}
}
}
void dfs(int level){
int cpMap[20][20];
memcpy(cpMap, map, 4 * 20 * 20);
if (level == 5){
int tmp = getMax();
if (maxx < tmp) maxx = tmp;
return;
}
for (int i = 1; i <= 4; ++i){
move_map(i);
dfs(level + 1);
memcpy(map, cpMap, 4 * 20 * 20);
}
}
int main(){
//freopen_s(new FILE*, "tes.text", "r", stdin);
cin >> n;
for (int i = 0; i < n; ++i){
for (int j = 0; j < n; ++j){
cin >> map[i][j];
}
}
dfs(0);
printf("%d", maxx);
}