1. 문제 : 백준 - 2048(Easy)
2. 틀린 이유 : 재귀에서 이전 상태를 저장하는 tmp array를 전역 변수로 선언. DFS가 진행됨에 따라서 tmp 상태도 함께 바뀌게 되어 이전 값을 올바르게 저장할 수 없다.
3. key idea : tmp array를 DFS 함수 안에서 선언한다. 함수가 끝날 때 자동으로 없어지기 때문에 서로 영향을 받지 않음.
4. 알아두면 좋을 것 :
(1) array를 지역 변수로 선언했을 때 다른 함수에서 인자로 받는 방법
int (* tmp)[21] 이렇게 선언해주면 된다. array 하나가 pointer를 의미하므로 2차원의 경우에는 [21]을 뒤에 붙여주면 된다.
3차원의 경우에는 int (* tmp)[21][21] 이런식으로 n-1개의 bracket을 추가해주면 된다.
2. 틀린 코드
#include <cstdio>
#include <iostream>
using namespace std;
int n;
int tmp[21][21];
int map[21][21];
int checked[21][21];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int path[5];
int ans;
void init(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
checked[i][j] = 0;
}
}
}
void copy(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
tmp[i][j] = map[i][j];
}
}
}
void debug(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", map[i][j]);
}
printf("\n");
}
}
void paste(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
map[i][j] = tmp[i][j];
}
}
}
int max_map(){
int ret = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(ret < map[i][j])
ret = map[i][j];
}
}
return ret;
}
void swap(int &x, int &y){
int tmp = x;
x = y;
y = tmp;
}
bool in_range(int x, int y){
return x >= 0 && x < n && y >= 0 && y < n;
}
void move1d(int x, int y, int d){
int nx = x + dx[d], ny = y + dy[d];
while(in_range(nx, ny) && map[nx][ny] == 0){
map[nx][ny] = map[x][y];
map[x][y] = 0;
x = nx; y = ny;
nx = x + dx[d], ny = y + dy[d];
}
if(in_range(nx, ny) && map[nx][ny] == map[x][y] && !checked[nx][ny]){
map[nx][ny] += map[x][y];
map[x][y] = 0;
checked[nx][ny] = 1;
}
}
void move2d(int d){
if(d == 0) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else if(d == 1){
for (int i = n-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else if(d == 2){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else {
for (int i = 0; i < n; i++) {
for (int j = n-1; j >= 0; j--) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
}
}
void simul(int cnt){
if(cnt == 5){
//debug();
int tmp = max_map();
if(tmp > ans)
ans = tmp;
return;
}
for(int i = 0 ; i < 4; i++){
init();
copy();
move2d(i);
simul(cnt + 1);
paste();
}
}
int main() {
// freopen("../input.txt", "r", stdin);
//freopen("../output.txt", "w", stdout);
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &map[i][j]);
}
}
simul(0);
printf("%d", ans);
return 0;
}
3. 맞은 코드
#include <cstdio>
#include <iostream>
using namespace std;
int n;
int tmp[21][21];
int map[21][21];
int checked[21][21];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int path[5];
int ans;
void init(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
checked[i][j] = 0;
}
}
}
void copy(int (*tmp)[21]){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
tmp[i][j] = map[i][j];
}
}
}
void debug(){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
printf("%d ", map[i][j]);
}
printf("\n");
}
}
void paste(int (*tmp)[21]){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
map[i][j] = tmp[i][j];
}
}
}
int max_map(){
int ret = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(ret < map[i][j])
ret = map[i][j];
}
}
return ret;
}
void swap(int &x, int &y){
int tmp = x;
x = y;
y = tmp;
}
bool in_range(int x, int y){
return x >= 0 && x < n && y >= 0 && y < n;
}
void move1d(int x, int y, int d){
int nx = x + dx[d], ny = y + dy[d];
while(in_range(nx, ny) && map[nx][ny] == 0){
map[nx][ny] = map[x][y];
map[x][y] = 0;
x = nx; y = ny;
nx = x + dx[d], ny = y + dy[d];
}
if(in_range(nx, ny) && map[nx][ny] == map[x][y] && !checked[nx][ny]){
map[nx][ny] += map[x][y];
map[x][y] = 0;
checked[nx][ny] = 1;
}
}
void move2d(int d){
if(d == 0) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else if(d == 1){
for (int i = n-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else if(d == 2){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
} else {
for (int i = 0; i < n; i++) {
for (int j = n-1; j >= 0; j--) {
if (map[i][j] != 0)
move1d(i, j, d);
}
}
}
}
void simul(int cnt){
if(cnt == 5){
//debug();
int tmp = max_map();
if(tmp > ans) {
ans = tmp;
// debug();
// for(int i = 0 ; i < 5; i++){
// printf("%d ", path[i]);
// }
// printf("\n");
}
return;
}
for(int i = 0 ; i < 4; i++){
int tmp[21][21];
init();
copy(tmp);
move2d(i);
path[cnt] = i;
simul(cnt + 1);
paste(tmp);
}
}
int main() {
//freopen("../input.txt", "r", stdin);
//freopen("../output.txt", "w", stdout);
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &map[i][j]);
}
}
simul(0);
printf("%d", ans);
return 0;
}
'알고리즘 > 오답노트' 카테고리의 다른 글
시간 복잡도 (0) | 2020.12.30 |
---|---|
시뮬레이션에서 문제 조건을 잘못 읽은 문제 (0) | 2020.12.26 |