Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- DFS
- Algorithm
- JavaScript
- Python
- aws
- spring boot
- 구현
- 알고리즘
- Priority Queue
- 코딩테스트
- 알고리듬
- Vue.js
- CSV
- programmers
- 코테
- django
- BFS
- SQL
- boj
- gpdb
- 시뮬레이션
- Linked list
- hash table
- GitHub
- Bruth Force
- 모의SW역량테스트
- Data Structure
- SWEA
- Back tracking
- Trie
Archives
- Today
- Total
hotamul의 개발 이야기
[Algorithm][C++] BOJ 12100 2048(Easy) 본문
myt-algorithm-practice/Samsung SW Certi Adv
[Algorithm][C++] BOJ 12100 2048(Easy)
hotamul 2021. 10. 24. 22:09url: https://www.acmicpc.net/problem/12100
12100번: 2048 (Easy)
첫째 줄에 보드의 크기 N (1 ≤ N ≤ 20)이 주어진다. 둘째 줄부터 N개의 줄에는 게임판의 초기 상태가 주어진다. 0은 빈 칸을 나타내며, 이외의 값은 모두 블록을 나타낸다. 블록에 쓰여 있는 수는 2
www.acmicpc.net
풀이 핵심
1. 완전 탐색 문제 (Bruth Force / Back Tracking)
2. map을 반시계 방향으로 (시계 방향인지 반시계 방향인지는 중요하지 않음) 회전시키는 함수와 위로 이동시키는 함수를 구현한다. (상 하 좌 우로 이동시키는 함수를 각각 구현하기는 번거롭기 때문)
3. 문제에서 가장 중요한 것은 이동시키는 함수를 어떻게 구현하는 것이냐 이다.
- "이미 합쳐진 숫자이므로 합쳐지면 안 돼!" 를 표시할 수 있는 flag와 이동시켜야 하는 위치를 나타내는 target을 이용했다.
- flag가 true이면 합쳐질 수 있어라는 뜻이고 false이면 합쳐질 수 없어 라는 뜻이다.
- 따라서 flag가 true이고 현재 이동할 위치에 있는 숫자 (temp[target][c]) 와 이동시켜야 하는 숫자 (map[r][c]) 가 같으면 더해 주는 방식으로 구현했다. (temp[target][c] += map[r][c]) 그리고 더 이상 합쳐지면 안 되므로 flag를 false로 바꿔준다.
- 위의 조건을 만족하지 않으면 target을 증가시키고 이동할 숫자 (map[r][c])를 이동할 위치에 이동시킨다. (temp[++target][c] = map[r][c])
4. 재귀 함수 형식의 solve를 통해 완전 탐색할 수 있도록 했다.
코드
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
int N, ans;
struct BOARD {
int map[20][20];
int get_max() { // 최대 구하는 함수
int ret = 0;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (ret < map[r][c]) {
ret = map[r][c];
}
}
}
return ret;
}
void rotate() { // 90도 회전
int temp[20][20];
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
temp[r][c] = map[c][N - r - 1];
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
map[r][c] = temp[r][c];
}
}
}
void up() { // 위로 이동시키는 함수
int temp[20][20] = { 0, };
for (int c = 0; c < N; c++) {
bool flag = false; // 이미 합쳐진 숫자이므로 더하면 안 돼!
int target = -1; // 숫자가 이동할 위치
for (int r = 0; r < N; r++) {
if (map[r][c] == 0) continue; // 이동 시킬 숫자가 0이라면 continue
/*flag가 true이고 이동할 위치의 숫자가 이동시킬 숫자와 같을 때 더한다.
여기서 target != -1 은 segmentation fault를 피하기 위해 넣었다*/
if (flag && target != -1 && temp[target][c] == map[r][c]) {
temp[target][c] += map[r][c];
flag = false; // 이제 이 숫자는 더 이상 합쳐질 수 없어!
}
// 위 조건이 아니라면
else {
temp[++target][c] = map[r][c];
flag = true; // 합쳐질 수 있어
}
}
}
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
map[r][c] = temp[r][c];
}
}
}
};
void solve(BOARD cur, int cnt) {
if (cnt == 5) {
int candi = cur.get_max();
if (ans < candi) ans = candi;
return;
}
for (int dir = 0; dir < 4; dir++) {
BOARD next = cur;
next.up();
solve(next, cnt + 1);
cur.rotate();
}
}
int main() {
BOARD board;
scanf("%d", &N);
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
scanf("%d", &board.map[r][c]);
}
}
solve(board, 0);
printf("%d", ans);
return 0;
}
'myt-algorithm-practice > Samsung SW Certi Adv' 카테고리의 다른 글
[Algorithm][C++] JUNGOL 4193: swat. 애벌레 키우기1 (0) | 2021.10.28 |
---|---|
[Algorithm][C++] SWEA 1249. [S/W 문제해결 응용] 보급로 문제 (0) | 2021.10.27 |
[Algorithm][C++] BOJ 13460 구슬 탈출 2 (0) | 2021.10.24 |
[Algorithm][C++] BOJ 20057 마법사 상어와 토네이도 (0) | 2021.10.17 |
[Algorithm][C++] BOJ 15686 치킨 배달 (0) | 2021.10.16 |
Comments